我的代码位于底部。我试图取两个字符串并根据我收到的编辑记录来更改它们。我写了我的代码,但我不明白为什么我会得到如此奇怪的输出。我的目标是首先存储两个字符串的值,然后将它们变成一个2D数组,但是我在这个目标的第一部分失败了。这就是问题所在:
创建符合以下条件的函数:
输入:编辑记录和2个原始字符串(3个字符串)
输出:包含编辑后两个对齐的2 d数组
示例:
s1 = “vintner”
s2 = “writers”
trans = “RIMDMDMMI”
R代表"替换" 我代表"插入" 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;
}
答案 0 :(得分:1)
您的问题实际上有两个部分:如何返回两个字符串?为什么我没有得到所需的输出?
C中的字符串是字符数组。你很少返回字符串。将字符数组与其最大长度一起传递给函数更常见,并填充该数组。 <string.h>
中的函数可以做到这一点。在我看来,一个好的设计模型是snprintf
:它填充缓冲区,注意不要溢出它,确保结果正确地以null结尾并返回缓冲区足够大时写入的字符数。最后一个属性允许您传递一个null的长度(以及NULL
指针的特殊情况),以找出您需要多少个字符并根据需要分配内存。
因此,您的函数原型可能如下所示:
int getAlignment(char *res1, char *res2, size_t n,
const char* s1, const char* s2, const char* trans);
除非结果字符串在您的情况下长度不同。
你也可以返回字符串,但你要么必须在堆上返回用malloc
分配的新内存,这意味着客户端代码必须显式地free
,或者指向已经存在的内存。当然,您只能返回一个字符串。
您可以将函数中的多个值作为结构返回。在将函数传递给函数或从函数返回时,结构不会衰减为指针。我将在下面的示例中使用该方法。
至于第二个问题:你的主要问题是你有三个字符串 - 两个源字符串和一个翻译字符串 - 但只保留两个索引。所有字符串都是独立遍历的;字符串的索引之间没有同步。
您可以随时附加到结果字符串。 “driving”字符串是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 *
。