标签: c-strings

为什么strdup被认为是邪恶的

我看过一些海报说这strdup是邪恶的.对此有共识吗?我使用它没有任何内疚感,并且没有理由比使用malloc/ 更糟糕memcpy.

我能想到的唯一可能strdup是声名远扬的是调用者可能会滥用它(例如,没有意识到他们必须释放返回的内存;尝试strcat到strdup'ed字符串的末尾).但是,malloc的字符串也没有被滥用的可能性.


感谢对那些认为这个问题无益的人的回复和道歉(投票结束).总结一下这些答复,似乎没有普遍的感觉strdup本身就是邪恶的,但是普遍的共识是它可以像C的许多其他部分一样被不恰当地或不安全地使用.

真的没有'正确'的答案,但为了接受一个,我接受了@nneoneo的答案 - 它同样可能是@R ..的答案.

c c-strings

26
推荐指数
4
解决办法
2万
查看次数

const char* 在哪里获得指向内存地址的指针?

这可能是一个简单的问题,但为什么 const char* 不需要指向的内存地址?

例子:

const char* a = "Anthony";
Run Code Online (Sandbox Code Playgroud)

并不是:

const char *a = // Address to const char
Run Code Online (Sandbox Code Playgroud)

像其他类型一样吗?

c c++ c-strings string-literals implicit-conversion

24
推荐指数
2
解决办法
2261
查看次数

使用C-string:"返回与本地变量关联的堆栈内存的地址"

我不是C程序员,所以我不熟悉C-string但新的我必须使用C库,所以这里是我的代码的缩短版本来演示我的问题:

char** ReadLineImpl::my_completion () {

    char* matches[1];


    matches[0] = "add";

    return matches;

}
Run Code Online (Sandbox Code Playgroud)

我收到警告:

警告 - 与返回的本地变量"matches"关联的堆栈内存的地址

我的应用程序似乎没有正常工作(可能是因为这个警告).

什么是警告,是否会引起任何问题?

c++ pointers c-strings

23
推荐指数
2
解决办法
5万
查看次数

在编译时确定#defined字符串长度

我有一个C程序(一个Apache模块,即程序经常运行),它将write()通过套接字转到0端接的字符串,所以我需要知道它的长度.

字符串#defined为:

#define POLICY "<?xml version=\"1.0\"?>\n" \
   "<!DOCTYPE cross-domain-policy SYSTEM\n" \
   "\"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n" \
   "<cross-domain-policy>\n" \
   "<allow-access-from domain=\"*\" to-ports=\"8080\"/>\n" \
   "</cross-domain-policy>\0"
Run Code Online (Sandbox Code Playgroud)

请问一种方法,比strlen(POLICY)+1在运行时使用更好(从而一次又一次地计算长度)?

一个预处理器指令,它允许POLICY_LENGTH在编译时设置?

c macros c-strings strlen c-preprocessor

21
推荐指数
3
解决办法
2万
查看次数

什么语言标准允许忽略固定大小数组上的空终止符?

我们正在将C代码转换为C++.
我注意到以下代码在C中定义得很好,

int main(){

  //length is valid. '\0' is ignored
  char  str[3]="abc";
}
Run Code Online (Sandbox Code Playgroud)

正如在Array初始化中所述:

"如果数组的大小已知,它可能比字符串文字的大小小一个,在这种情况下,终止空字符将被忽略."

但是,如果我要在C++中构建相同的代码,我会收到以下C++错误:

error: initializer-string for array of chars is too long
[-fpermissive]    char  str[3]="abc";
Run Code Online (Sandbox Code Playgroud)

我希望有人可以对此进行阐述.

问题:
代码示例是否在所有C语言标准中都有效?
它在所有C++语言标准中都无效吗?
是否有一种语言在一种语言中有效而在另一种语言中无效?

c c++ arrays c-strings array-initialization

21
推荐指数
2
解决办法
857
查看次数

C 中的 '\0' 和 printf()

在 C 的入门课程中,我了解到,在存储字符串时,存储的字符串\0末尾带有空字符。但是,如果我想打印一个字符串,尽管printf("hello")我发现它不\0以以下语句结尾,该怎么办

printf("%d", printf("hello"));

Output: 5
Run Code Online (Sandbox Code Playgroud)

但这似乎不一致,据我所知,像字符串这样的变量存储在主内存中,我猜在打印某些内容时它也可能存储在主内存中,那么为什么会有区别呢?

c printf stdout c-strings

21
推荐指数
5
解决办法
1983
查看次数

是sprintf(缓冲区,"%s [...]",缓冲区,[...])安全吗?

我看到使用这个模式连接到我正在处理的一些代码中的字符串:

sprintf(buffer, "%s <input type='file' name='%s' />\r\n", buffer, id);
sprintf(buffer, "%s</td>", buffer);
Run Code Online (Sandbox Code Playgroud)

而且我很确定它不安全C.你会注意到buffer它既是输出又是第一个输入.

除了缓冲区溢出的明显可能性之外,我相信不能保证缓冲区在函数的开始和结束之间不会发生变化(即,无法保证缓冲区的状态在执行功能).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, " <input type='file' name='%s' />\r\n", id);
Run Code Online (Sandbox Code Playgroud)

替换这个.

c printf c-strings

20
推荐指数
2
解决办法
1万
查看次数

C字符串在C和C++中为大写

当我在C++中组合一个大写的函数时,我注意到我没有在C中收到预期的输出.

C++函数

#include <iostream>
#include <cctype>
#include <cstdio>

void strupp(char* beg)
{
    while (*beg++ = std::toupper(*beg));
}

int main(int charc, char* argv[])
{
    char a[] = "foobar";
    strupp(a);
    printf("%s\n", a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

按预期输出:

FOOBAR
Run Code Online (Sandbox Code Playgroud)


C功能

#include <ctype.h>
#include <stdio.h>
#include <string.h>

void strupp(char* beg)
{
    while (*beg++ = toupper(*beg));
}

int main(int charc, char* argv[])
{
    char a[] = "foobar";
    strupp(a);
    printf("%s\n", a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是第一个字符缺失的预期结果

OOBAR
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么在C中编译时结果会被截断?

c c++ string c-strings uppercase

20
推荐指数
3
解决办法
1万
查看次数

将枚举与字符串关联的正确方法

假设我在整个程序中经常使用一些字符串(用于存储状态和类似的东西).字符串操作可能很昂贵,所以无论何时解决它们我都想使用枚举.到目前为止,我已经看到了几个解决方案:

typedef enum {
    STRING_HELLO = 0,
    STRING_WORLD
} string_enum_type;

// Must be in sync with string_enum_type
const char *string_enumerations[] = {
    "Hello",
    "World"
}
Run Code Online (Sandbox Code Playgroud)

我经常遇到的另一个:

typedef enum {
    STRING_HELLO,
    STRING_WORLD
} string_enum_type;

const char *string_enumerations[] = {
    [STRING_HELLO] = "Hello",
    [STRING_WORLD] = "World"
}
Run Code Online (Sandbox Code Playgroud)

这两种方法的缺点是什么?还有更好的吗?

c enums c-strings

19
推荐指数
1
解决办法
1186
查看次数

为什么不string :: data()提供一个Mutable char*?

array,stringvector所有得到了data方法,该方法:

返回指向用作元素存储的基础数组的指针.指针是范围[ data(); data() + size())即使容器为空,也始终是有效范围.[ 来源 ]

此方法const以所有适用容器的可变和版本提供,例如:

T* vector<T>::data();
const T* vector<T>::data() const;
Run Code Online (Sandbox Code Playgroud)

所有适用的容器,也就是除了string只提供const版本:

const char* string::data() const;
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?为什么会被string贬低,何时char* string::data()会如此有用?

c++ string containers c-strings c++11

18
推荐指数
2
解决办法
4082
查看次数