[英]Cast char to char array or char array to char?
所以,假设我有一个char,我想在一行代码中将它strcat()转换为char数组。 对于[非实际]示例:
strcat("ljsdflusdfg",getchar());
或者我想反过来说,无论数据类型如何,连接或类型转换字符串的适当功能是什么? 或者也许有一些我遗漏的语法......
这是一个例子。 它编译得很好,但崩溃。
char* input(){
char* inp="";
while(1){
char c=getchar();
if(c){
if(c=='\n'||c==EOF){
break;
}else{
strcat(inp,(char*)c);
}
}
}
return inp;
}
strcat
将其参数视为指向以空字符结尾的字符串的指针。 把一个char
变成一个char *
是危险的,我可以想象没有理由它会有用(不要暗示你尝试它是愚蠢的 - 每个人在学习时都犯了愚蠢的错误。这就是为什么我们在这里。 )
原因是它会解释单字节char
,加上围绕该char
的额外sizeof(char*) - sizeof(char)
(通常为3)字节作为指针,指向......任何地方。 你无法知道它指向的位置,因为其中3个字节超出了你的控制范围,因此无法知道它是否指向有效数据。
您可以将此作为第二种方法:
strcat(inp, &c);
这一次,你会做得更好,因为&c
是char *
类型的表达式,不需要强制转换。 但同样, strcat
假设它的参数是一个以空字符结尾的字符串,并且因为你无法在char
数据之后保证一个空字节,所以这不行。
最好的方法是:
size_t len = strlen(inp); // this may already be calculated somewhere else
...
inp[len++] = c; // add c as the last character, and adjust our len
inp[len] = '\0'; // add a new nul terminator to our string
更新:
实际上,我撒了谎。 最好的方法是使用标准库函数fgets
,它似乎或多或少地做了你想要做的事情。 说实话我忘记了,但如果这是家庭作业,你的教授可能不会要你使用fgets
这样你就可以学习如何手动完成。 但是,如果这不是家庭作业,那么fgets
正是你正在寻找的。 (实际上,第三种方法正在重新实现fgets
或fgets
的功能。)
我还要在input
函数上添加一些其他注释:
char* inp = "";
将指向只读数据。 C标准中的缺陷(用于向后兼容性)允许将字符串文字分配给char*
类型而不是const char *
类型,因为它(IMHO)应该是。 malloc
函数保留一些数据,跟踪你在函数中使用了多少,并使用realloc
函数,如果你最终需要更多空间来存储它。 如果你需要帮助,我相信你会回到这里(希望不会太早 )另一个问题。 :) getchar()
返回一个int
,因为EOF
被定义为超出char
的正常范围。 为了区分任何char
和EOF
,最好将c
设为int
。 否则,完全有效的角色可能会发出EOF
信号。 但是,当您将c
添加到字符串时,请务必将其转换为char
。 strcat(inp,(char*)c);
那就是尝试将内存的内容连接到“c”(作为内存位置),直到找到零为止。
更好的方法是创建一个空字符串,其中包含您认为合理的最大大小,用零填充,然后在当前最后位置插入'c'
如果你想串联一个char
到串上,你可以用strncat()
和指定的字符数来连接为1
。 但请注意:
char
对象来获取地址(所以你不能直接连接getchar()
的结果。 例如:
char str[5] = "foo";
char c;
int ch;
if ((ch = getchar()) != EOF) {
c = ch;
strncat(str, &c, 1);
}
在C99中,您可以使用复合文字 ,第二个限制不适用:
char str[5] = "foo";
int ch;
if ((ch = getchar()) != EOF) {
strncat(str, &(char){ ch }, 1);
}
这不起作用,因为* inp char指针没有任何内存备份它。 当你声明它是char * inp =“”;时,你只给它一个空字符串的地址。 如果您给出了以下声明char * inp =“abcdefg”,那么在覆盖'\\ 0'并遇到麻烦之前,您可以写入7个字符。
当您输入越来越多的字符时,您将需要动态增加后备内存的大小。 您还将遇到知道何时释放内存以避免内存泄漏的问题。
另外,你的strcat需要在c之前有'&'。
一种简单的方法是使用snprintf:
char newString[50+1];
snprintf(newString, sizeof(newString), "%s%c", "ljsdflusdfg", getchar());
这是一个简单的解决方案,但确实要求您大致知道字符串将提前有多大。
注意:我使用+1来提醒自己需要有空终止空间,并且snprintf优于sprintf,因为它被赋予缓冲区的大小以防止缓冲区溢出。
首先,您将返回指向堆栈分配数组的指针。 这是未定义的行为。 其次,您正在尝试将字符写入未分配的内存中。 第三, inp
的类型是const char*
而不是char*
。
你想要的东西:
char* input(char *dest) {
strcpy(dest,"");
while(1){
char c=getchar();
if(c){
if(c=='\n'||c==EOF){
break;
}else{
strcat(inp,&c);
}
}
}
return dest;
}
您的代码崩溃,因为strcat期望其两个参数都以空字符结尾的字符串。
如果要连接char,则需要首先从中创建以null结尾的字符串。
char c[2] = {0,0};
c[0] = getchar();
strcat(inp, c);
但是不要使用strcat ,除非你能保证输入字符串已为该额外字符分配了空间。 更好的strncat,它还包括第一个参数(dest)中空间量的参数。
我建议你阅读这首。
将char转换为char数组?
这就像是说你想把一个字符串转换成字符串。
你不能直接这样做。
而不是char,将它放在一个数组(myChar [])中。
之后,用你原来的char数组来strcat它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.