Tag: c strings

在引用的字符串中展开宏

可能重复: C宏来创建字符串 我有一个函数接受一个char*类型的参数,像f(“string”); 如果字符串参数是在函数调用中由the-fly定义的,那么如何在字符串体内扩展宏呢? 例如: #define COLOR #00ff00 f(“abc COLOR”); 相当于 f(“abc #00ff00″); 但是不执行扩展,函数接收字面上的abc COLOR 。 特别是,我需要将宏扩展为\”#00ff00\” ,以便将引用的标记与传递给f()的其余字符串参数连接起来,包括引号; 也就是说,预处理器必须完成他的工作并欢迎编译器从f(“abc COLOR”);转换代码f(“abc COLOR”); 到f(“abc \”#00ff00\””);

如何编写更好的strlen函数?

我正在阅读“编写伟大的代码卷2”并显示以下strlen inslementation: int myStrlen( char *s ) { char *start; start = s; while( *s != 0 ) { ++s; } return s – start; } 这本书说这种实现对于没有经验的C程序员来说是典型的。 在过去的11年里,我一直在使用C语言进行编码,我无法在C中看到如何编写比这更好的函数(我可以想到在汇编中编写更好的东西)。 如何在C中编写比这更好的代码? 我看了glibc中strlen函数的标准库实现,我无法理解它的大部分内容。 在哪里可以找到有关如何编写高度优化代码的更好信息?

是strtol,strtod不安全吗?

似乎strtol()和strtod()有效地允许(并强制)你在字符串中抛弃constness: #include #include int main() { const char *foo = “Hello, world!”; char *bar; strtol(foo, &bar, 10); // or strtod(foo, &bar); printf(“%d\n”, foo == bar); // prints “1”! they’re equal *bar = ‘X’; // segmentation fault return 0; } 上面,我自己没有演出。 但是, strtol()基本上将我的const char *转换为char *给我,没有任何警告或任何东西。 (事实上​​,它不允许你键入bar作为const char * ,因此强制类型中的不安全更改。)这不是真的很危险吗?

在C中打印字符串的一部分

有没有办法只打印部分字符串? 例如,如果我有 char *str = “hello there”; 有没有办法只打印”hello” ,记住我要打印的子字符串是可变长度,而不是总是5个字符? 我知道我可以使用for循环和putchar或者我可以复制数组,然后添加一个空终止符,但我想知道是否有更优雅的方式?

在我的情况下strncpy或strlcpy

当我想将src_str复制到dst_arr时,我应该使用什么?为什么? char dst_arr[10]; char *src_str = “hello”; PS:在阅读了很多关于strncpy和strlcpy 好坏的事情之后,我的头比我的电脑磁盘旋转得更快。 注意:我知道strlcpy无处不在。 这不是问题所在。

字符串和char数组如何在C中工作?

我见过的导游似乎没有解释得这么好。 我的意思是,你可以为char*分配内存,或者写char[25]而不是? 有什么不同? 还有文字,不能被操纵? 如果要将固定字符串分配给变量,该怎么办? 比如, stringVariable = “thisIsALiteral” ,那么你之后如何操纵呢? 有人可以直接在这里设置记录吗? 在最后一种情况下,使用文字,你如何处理空终止? 我觉得这很令人困惑。 编辑:真正的问题似乎是,据我所知,你必须兼顾这些不同的结构,以完成甚至简单的事情。 例如,只有char *可以作为参数或返回值传递,但只能为char[]分配文字和修改。 我觉得很明显,我们经常/总是需要能够做到这两点,这就是我的陷阱所在。

从函数返回’c_str’

这是我在网上找到的一个小型图书馆: const char* GetHandStateBrief(const PostFlopState* state) { static std::ostringstream out; // … rest of the function … return out.str().c_str() } 在我的代码中,我这样做: const char *d = GetHandStateBrief(&post); std::cout<< d << std::endl; 现在,起初d包含垃圾。 然后我意识到,当函数返回时,我从函数中获取的C字符串被销毁,因为在堆栈上分配了std::ostringstream 。 所以我补充说: return strdup( out.str().c_str()); 现在我可以从函数中获取我需要的文本。 我有两个问题: 我理解正确吗? 后来我注意到out (类型为std::ostringstream )分配了静态存储。 这是不是意味着在程序终止之前该对象应该留在内存中? 如果是这样,那为什么不能访问该字符串?

为什么strdup被认为是邪恶的

我看过一些海报,说明strdup是邪恶的。 对此有共识吗? 我使用它没有任何内疚感,并且没有理由比使用malloc / memcpy更糟糕。 我唯一可以想到的可能是获得声誉的是调用者可能会滥用它(例如,没有意识到他们必须释放返回的内存;尝试strcat到strdup’ed字符串的末尾)。 但是,malloc的字符串也没有被滥用的可能性。 感谢对那些认为这个问题无益的人的回复和道歉(投票结束)。 总结一下这些回复,似乎没有普遍认为strdup本身就是邪恶的,但是普遍认为它可以像C的许多其他部分一样被不正当地或不安全地使用。 真的没有’正确’的答案,但为了接受一个,我接受了@nneoneo的答案 – 它同样可能是@R ..的答案。

sprintf(缓冲区,“%s ”,缓冲区,)是否安全?

我看到使用这种模式连接到我正在处理的一些代码中的字符串: sprintf(buffer, “%s \r\n”, buffer, id); sprintf(buffer, “%s”, buffer); 而且我很确定它不安全C.你会发现buffer既是输出又是第一个输入。 除了缓冲区溢出的明显可能性之外 ,我相信无法保证缓冲区在函数的开始和结束之间不会发生变化(即,无法保证缓冲区的状态在执行function)。 sprintf的签名还指定restrict目标字符串。 我还记得一篇关于memcpy中的推测性写作的报告,我认为没有理由为什么某个C库可能在sprintf中做同样的事情。 当然,在这种情况下,它会写入其来源。 这种行为安全吗? 仅供参考,我建议: char *bufEnd = buffer + strlen(buffer); /* sprintf returns the number of f’d and print’d into the s */ bufEnd += sprintf(bufEnd, ” \r\n”, id); 替换这个。