也许是微不足道的,但我只是学习C而我讨厌用2行做什么,可以用一个做什么(只要它不会混淆代码当然)。
无论如何,我通过一次附加一个字符来构建字符串。我这样做是通过跟踪正在构建的字符串的char索引,以及输入文件字符串的(行)索引。
str[strIndex] = inStr[index];
str[strIndex + 1] = '\0';
str用于临时存储输入行中的一个单词。 我每次添加一个字符时都需要附加终止符。
我想我想知道的;有没有办法在一个语句中组合这些,而不使用strcat()(或每次我开始一个新单词时清除str与memset())或创建其他变量?
答案 0 :(得分:2)
简单解决方案:在向其添加任何内容之前将字符串清零。 NUL
已经提前到达每个位置。
// On the stack:
char str[STRLEN] = {0};
// On the heap
char *str = calloc(STRLEN, sizeof(*str));
在calloc
的情况下,对于大型分配,您甚至无法支付显式归零内存的成本(在批量分配模式下,它直接从OS请求内存,这可能是懒惰的零-ed(Linux)或在您提出要求之前已经进行了背景调整(Windows)。
显然,你可以通过推迟NUL
字符串的终止直到你完成它的构建来避免这项工作量,但是如果你可能需要将它用作C风格的字符串,任何时候,保证它始终NUL
- 在前面终止并非不合理。
答案 1 :(得分:1)
声明一个char数组:
char str[100];
,或者
char * str = (char *)malloc(100 * sizeof(char));
在循环中逐个添加所有字符:
for(i = 0; i<length; i++){
str[i] = inStr[index];
}
用空字符(循环外)完成它:
str[i] = '\0';
答案 2 :(得分:1)
我相信你现在这样做的方式是满足你
的最佳要求1)没有字符串全为零以
开头2)在每个阶段,字符串都是有效的(因为总是有终止)。
基本上你想每次添加两个字节。真正最简洁的方法就是你现在这样做。
如果您希望通过使用&#34;一行&#34;来使代码看起来更整洁。但是没有调用函数那么可能是一个宏:
#define SetCharAndNull( String, Index, Character ) \
{ \
String[Index] = (Character); \
String[Index+1] = 0; \
}
并使用它:
SetCharAndNull( str, strIndex, inStr[index]);
否则,我能想到的唯一可以实现结果的是写一个&#34;字&#34;在大多数情况下,一次(两个字节,所以unsigned short
)。你可以通过一些可怕的类型转换和指针算法来做到这一点。我强烈建议不要这样做,因为它不会非常易读,也不会很便携。它必须为特定的字节顺序编写,在需要对字访问进行对齐的系统上也会出现问题。
[编辑:添加以下内容] 为了完整起见,我提出了我在这里提到的那个糟糕的解决方案:
*((unsigned short*)&str[strIndex]) = (unsigned short)(inStr[index]);
这是将str[strIndex]
的指针类型转换为unsigned short
,在我的系统(OSX)上是16位(两个字节)。然后将该值设置为16位版本的inStr[index]
,其中前8位为零。因为我的系统是小端,所以第一个字节将包含最不重要的字节(即字符),第二个字节将从字的顶部开始为零。但正如我所说,不要这样做!它不会在大端系统上工作(你必须在左移8中添加),这也会导致某些处理器上的对齐问题,在这些处理器上你无法在非16位对齐的地址上访问16位值(这将是8位对齐的设置地址)
答案 3 :(得分:0)
首先,C没有字符串,只有char数组。因此,如果您不想使用其他辅助功能,则必须像往常一样逐个分配每个字符。但\ 0字符只出现在char数组的末尾。