问题描述
我正在尝试理解作为指示器的黑色巫毒魔术师,在以下情况下我无法理解。 我对getline()的第一个参数的理解很笨拙,因此我想这全都归结为它的类型,与第二个示例中的单词不同。
以下是摘录自一个函数的摘要,该函数加载文件(单词词典)并逐行读取其内容。为什么tolower()在第一个示例中起作用:
int l;
size_t len = 0;
char *word = NULL;
while ((l = getline(&word,&len,fp)) != -1)
{
for (char *p = word; *p; ++p) *p = tolower(*p);
// Irrelevant code below
}
但是在第二个示例中,在尝试从第一个字符分配tolower()返回之后,出现了段错误:
char *word = "POTATO";
for (char *p = word; *p; ++p) *p = tolower(*p);
解决方法
浏览C标准(6.4.5字符串文字)就足够了
7不确定这些数组是否有区别,只要它们的 元素具有适当的值。 如果程序尝试执行以下操作 修改这样的数组,行为是不确定的。
首先,字符串文字是具有静态存储持续时间的字符数组。
例如,在C语言中,字符串文字"POTATO"
的类型为char[7]
。
这是一个演示程序。
#include <stdio.h>
int main(void)
{
printf( "sizeof( \"POTATO\" ) = %zu\n",sizeof( "POTATO" ) );
return 0;
}
程序输出为
sizeof( "POTATO" ) = 7
用于表达式数组的异常例外情况(例如,用作运算符sizeof
的操作数)将转换为指向其第一个元素的指针。
所以在这个声明中
char *word = "POTATO";
(仅出于说明目的)可以被重写为
char *word = &"POTATO"[0];
用作初始化程序的字符串文字将转换为指向其首个字母'P'
的指针。
为避免在C ++中更改字符串文字(与C字符串文字相反)的错误,应使用常量字符数组。
因此,在C ++中,您必须编写
const char *word = "POTATO";
建议也使用限定符const
在C中声明指向字符串文字的指针。
提出我的问题后,我决定重新检查getline()文档。 根据它,第一个参数是char ** lineptr。意味着它是指向char的指针。 更具体地说:
getline()从流中读取整行,并存储 包含文本到* lineptr
的缓冲区
由于我对双指针和一般指针的理解仍然有限,因此我决定阅读getline()的代码,试图了解正在发生的事情:
https://dev.w3.org/libwww/Library/src/vms/getline.c
这是我所了解的内容,也是我对第二个示例的更正,以免出现段错误。
char word[] = "POTATO";
for (char *p = word; *p; ++p) *p = tolower(*p);
然后试图真正理解纠正的原因,我还搜索了char数组和char指针之间的差异,并且发现并阅读了以下内容:
https://overiq.com/c-programming-101/character-array-and-character-pointer-in-c/
我了解到的是,数组的元素可以单独修改。但是chars指针(字符串文字)不能。
我认为后者可以解决,但不可能。因此,我在第二个示例中的错误。 我试图修改char指针所指向的值,但由于缺乏对Black Mojo的了解,因此遇到了段错误。
现在我了解得更多了,这次旅行很愉快。
请随时编辑或添加您的见解。