以下代码在第2行接收seg错误:
char *str = "string";
str[0] = 'z'; // could be also written as *str = 'z'
printf("%s\n", str);
Run Code Online (Sandbox Code Playgroud)
虽然这非常有效:
char str[] = "string";
str[0] = 'z';
printf("%s\n", str);
Run Code Online (Sandbox Code Playgroud)
经过MSVC和GCC测试.
说我有以下内容:
char* string = "Hello, how are you?";
Run Code Online (Sandbox Code Playgroud)
是否可以只打印出该字符串的最后5个字节?那么前5个字节呢?是否有一些变化printf可以允许这个?
令人惊讶的简单/愚蠢/基本问题,但我不知道:假设我想让我的函数的用户返回一个C字符串,其长度我不知道在函数的开头.我可以在开始时仅在长度上放置上限,并且根据处理,尺寸可能缩小.
问题是,分配足够的堆空间(上限)然后在处理期间终止字符串是否有任何问题?即如果我在分配的内存中间插入'\ 0',(a.)是否free()仍能正常工作,并且(b.)'\ 0'之后的空格变得无关紧要?一旦'\ 0'被添加,内存是否会被返回,或者它是否位于占用空间直到free()被调用?将这个悬空空间留在那里通常是不好的编程风格,为了节省一些前期编程时间,在调用malloc之前计算必要的空间?
为了给出这个上下文,假设我想删除连续的重复项,如下所示:
输入"你好oOOOo !!" - >输出"Helo oOo!"
...以及下面的一些代码显示了我如何预先计算操作产生的大小,有效地执行两次处理以使堆大小正确.
char* RemoveChains(const char* str)
{
if (str == NULL) {
return NULL;
}
if (strlen(str) == 0) {
char* outstr = (char*)malloc(1);
*outstr = '\0';
return outstr;
}
const char* original = str; // for reuse
char prev = *str++; // [prev][str][str+1]...
unsigned int outlen = 1; // first char auto-counted
// Determine length necessary by mimicking processing
while (*str) {
if (*str != …Run Code Online (Sandbox Code Playgroud) 在C++中执行此操作
char* cool = "cool";
Run Code Online (Sandbox Code Playgroud)
编译好,但给了我一个警告:
不推荐将字符串常量转换为char*.
我永远不会故意使用C风格的字符串std::string,但以防我问这个问题:
在没有const修饰符的情况下声明C风格的字符串是不好的做法?如果是这样,为什么?
在终止字符串时,在我看来逻辑上char c=0等同于char c='\0',因为"null"(ASCII 0)字节是0,但通常人们倾向于这样做'\0'.这纯粹是出于偏好还是应该是一个更好的"实践"?
什么是首选?
编辑: K&R 说:"字符常量'\0'表示值为零的字符,空字符.'\0'经常编写而不是0强调某些表达式的字符性质,但数值只是0.
我用C编写了这段小代码来测试C中的memcmp() strncmp() strcmp()函数.
这是我写的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *word1="apple",*word2="atoms";
if (strncmp(word1,word2,5)==0)
printf("strncmp result.\n");
if (memcmp(word1,word2,5)==0)
printf("memcmp result.\n");
if (strcmp(word1,word2)==0)
printf("strcmp result.\n");
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释我的差异,因为我对这三个功能感到困惑吗?
我的主要问题是我有一个文件,我在其中标记它的行,问题是,当我将文件中的"atoms"字标记时,我必须停止标记化的过程.
我第一次尝试strcmp()但不幸的是当它到达文件中放置"原子"这个词的时候它没有停止并且它继续,但当我使用它memcmp()或strncmp()它停止时我很高兴.
但后来我想,如果有一个字符串,其中前5个字母是a,t,o,m,s,并且这些字母后面跟着其他字母.
不幸的是,我的想法是正确的,因为我使用上面的代码测试它,通过初始化word1为"atomsaaaaa"和word2原子,memcmp()并strncmp()在if语句中返回0.另一方面,strcmp()它没有.似乎我必须使用strcmp().
对于常规C字符串,空字符'\0'表示数据的结尾.
那么std::string,我可以使用嵌入空字符的字符串吗?
我不完全确定如何在C中执行此操作:
char* curToken = strtok(string, ";");
//curToken = "ls -l" we will say
//I need a array of strings containing "ls", "-l", and NULL for execvp()
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?
我有一个看起来像的C字符串"Nmy stringP",其中N和P可以是任何字符.如何"my string"在C中编辑它?
我看过一些海报说这strdup是邪恶的.对此有共识吗?我使用它没有任何内疚感,并且没有理由比使用malloc/ 更糟糕memcpy.
我能想到的唯一可能strdup是声名远扬的是调用者可能会滥用它(例如,没有意识到他们必须释放返回的内存;尝试strcat到strdup'ed字符串的末尾).但是,malloc的字符串也没有被滥用的可能性.
感谢对那些认为这个问题无益的人的回复和道歉(投票结束).总结一下这些答复,似乎没有普遍的感觉strdup本身就是邪恶的,但是普遍的共识是它可以像C的许多其他部分一样被不恰当地或不安全地使用.
真的没有'正确'的答案,但为了接受一个,我接受了@nneoneo的答案 - 它同样可能是@R ..的答案.