2015-03-02 122 views
0

我的代码位于底部。我试图采取两个字符串,并根据我收到的编辑抄本来更改它们。我写了我的代码,但我不明白为什么我得到这样一个奇怪的输出。我的目标是首先存储这两个字符串的值,然后将它们变成一个二维数组,但是我没有参与那个目标的第一部分。这里的问题:字符对齐怪异输出

创建,以满足以下的函数:

输入:编辑转录,和2个原始字符串(3串)

输出:含有两种比对后编辑一个2 d阵列

实施例:

s1 = “vintner” 
s2 = “writers” 
trans = “RIMDMDMMI” 

R表示 “替换” I代表 “插入” M代表 “匹配” d代表 “删除” 答:

alignment={“v_intner_”, 
“wri_t_ers”}; //return a 2d array 

函数原型:

char** getAlignment(char* s1, char* s2, char* s3); 

这里是我下面的代码:

char TestS1[] = "vintner"; 
char TestS2[] = "writers"; 
char TestS3[] = "RIMDMDMMI"; 
char twoDarray[2][10]; 

char** getAlignment(char* s1, char* s2, char* s3){ 
    char transTemp[n]; 
    char s1Temp[n]; 
    char s2Temp[n]; 
    char sOne[n]; 
    char sTwo[n]; 
    strcpy(sOne, s1); 
    strcpy(sTwo, s2); 
    int jj; 
    strcpy(transTemp, s3); 
    int kk; 
    for(jj=0, kk=0; jj<n, kk<n; jj++, kk++){ 

     if(transTemp[jj]=='R') 
     { 
      s1Temp[kk] = sOne[jj]; 
      s2Temp[kk] = sTwo[jj]; 
     } 

     if(transTemp[jj]=='I'){ 
      s1Temp[kk] = '_'; 
      s1Temp[kk+1] = sOne[jj]; 
      s2Temp[kk] = sTwo[jj]; 
      kk++; 
     } 

     if(transTemp[jj] == 'M'){ 
      s1Temp[kk] = sOne[jj]; 
      s2Temp[kk] = sTwo[jj]; 
     } 

     if(transTemp[jj] == 'D'){ 
      s2Temp[kk] = '_'; 
      s2Temp[kk+1] = sTwo[jj]; 
      s1Temp[kk] = sOne[jj]; 
      kk++; 
     } 


    } 

    printf("\ns1Temp = %s\n", s1Temp); 
    printf("\ns2Temp = %s\n", s2Temp); 


    return 0; 
} 

main() 
{ 
printf("The new method returns: ", getAlignment(TestS1,TestS2,TestS3)); 
return 0; 
} 
+1

无格式说明在这里:'的printf( “新方法返回:” getAlignment(TestS1,TestS2,TestS3));' – 2015-03-02 06:55:07

+0

是啊,感谢指出了这一点。但是,我并不在意printf语句发生了什么。我只是想调用这个函数。我关注的值被打印在函数中。 – 2015-03-02 06:59:24

+0

你正试图返回一个'int'函数来返回一个'char **' – 2015-03-02 07:00:19

回答

1

你的问题真有两部分:如何返回两个字符串?为什么我没有获得期望的输出?

C中的字符串是字符数组。你很少返回字符串。将字符数组传递给函数以及其最大长度并填充该数组更为常见。 <string.h>中的功能可以做到这一点。在我看来,一个好的设计模型是:snprintf:它填充缓冲区,注意不要溢出它,确保结果正确地以null结尾,并返回缓冲区足够大时写入的字符数。最后一个属性允许你传递一个空值(并且作为一个特殊情况,指针为NULL),以找出需要多少个字符并根据需要分配内存。

所以原型的功能看起来是这样的:

int getAlignment(char *res1, char *res2, size_t n, 
    const char* s1, const char* s2, const char* trans); 

除了生成的字符串可能是你的情况不同的长度。

您也可以返回一个字符串,但你要么必须在堆上,这意味着客户端代码必须明确free它,或指针到现有存储返回与malloc分配新的内存。当然,您可以只返回一个字符串。

您可以从函数返回多个值作为结构体。将函数传递给函数或从函数返回时,结构不会衰减为指针。我将在下面的示例中使用该方法。

至于第二个问题:你的主要问题是你有三个字符串 - 两个源字符串和一个翻译字符串 - 但只保留两个索引。所有字符串都是独立遍历的;字符串的索引之间没有同步。

您随时追加到结果字符串。 “驱动”字符串是trenslation字符串,所以您只能通过主循环来遍历。

要注意的另一件事是您不需要制作源字符串的副本。这不仅是必要的,而且也是危险的,因为strcpy可能会溢出缓冲区。使用strncpy来处理溢出会截断输入字符串。

我已经更新您的实现:

#include <stdio.h> 
#include <string.h> 

#define N 10 

struct Result { 
    char res1[N]; 
    char res2[N]; 
}; 

struct Result getAlignment(const char* s1, const char* s2, const char* trans) 
{ 
    struct Result res; 

    int j1 = 0;    // index into s1 
    int j2 = 0;    // index into s2 
    int n = N - 1;   // leave 1 char for null terminator 

    while (*trans) { 

     if (*trans == 'R') { 
      if (j1 < n) res.res1[j1++] = *s1++; 
      if (j2 < n) res.res2[j2++] = *s2++; 
     } 

     if (*trans == 'I'){ 
      if (j1 < n) res.res1[j1++] = '_'; 
      if (j1 < n) res.res1[j1++] = *s1++; 
      if (j2 < n) res.res2[j2++] = *s2++; 
     } 

     if (*trans == 'M') { 
      if (j1 < n) res.res1[j1++] = *s1++; 
      if (j2 < n) res.res2[j2++] = *s2++; 
     } 

     if (*trans == 'D') { 
      if (j1 < n) res.res1[j1++] = *s1++; 
      if (j2 < n) res.res2[j2++] = '_'; 
      if (j2 < n) res.res2[j2++] = *s2++; 
     } 

     trans++; 
    } 

    // null-terminate strings 
    res.res1[j1] = '\0'; 
    res.res2[j2] = '\0'; 

    return res; 
} 

int main() 
{ 
    char *str1 = "vintner"; 
    char *str2 = "writers"; 
    char *trans = "RIMDMDMMI"; 

    struct Result res = getAlignment(str1, str2, trans); 

    printf("%s\n%s\n\n", res.res1, res.res2); 

    return 0; 
} 

注意事项:

  • 翻译字符串指针通过,从而节省了指数运行。

  • 仅当有足够的空间时,才会将结果字符串附加到后面。您可以将N更改为5,并查看结果字符串在4个字符后如何截断,从而丢失信息,但会防止缓冲区溢出。

  • 结果字符串索引和源字符串指针随着你的增加而增加。

  • 只能读取源字符串。 (这就是为什么复制没有意义。)所以它们应该在函数签名中为const char *