【问题标题】:Unable to print a char* string无法打印 char* 字符串
【发布时间】:2017-04-24 01:12:30
【问题描述】:

我不清楚我的程序出了什么问题,这是一个简单的代码来打开一个文件,从中读取第一行,然后打印它。但程序不断崩溃。我的文本文件的实际内容是一句话:测试我的代码。

int main(void)
{
FILE *stream;
char *s;
stream = fopen("input.txt", "r");
fscanf(stream, " %s", &s);

printf("%s", s);


fclose(stream);
return 0;
}

我被指示不要使用 <string.h> 中的库函数

【问题讨论】:

  • 1.你不检查fopen 的结果。 2. s 是一个未初始化的指针——你认为数据在哪里?
  • char s[16]; fgets(s, sizeof s, stream); 而不是 char *s;...fscanf(stream, " %s", &s);
  • 如果您使用的是 GCC,请始终使用 gcc -Wall -Werror 进行编译。
  • char *s; ... fscanf(stream, " %s", &s); --> char s[100]; fgets(s, sizeof s, stream);

标签: c string printf


【解决方案1】:

s 是一个未初始化的指针。你需要为fscanf分配一些内存来写入。

【讨论】:

  • 我把它初始化为:char *s = NULL;但程序仍然崩溃
  • 这不提供任何可写入的内存。
  • 您可以使用堆栈上的内存(char s[10] 在堆栈上分配 10 个字符)或使用 malloc 的动态内存分配。
【解决方案2】:
char *s;

分配保存内存地址所需的字节数(在大多数系统上为 32/64 位)。 但是由于您没有初始化指针,它的值(它指向的地址)是未定义的。

Ergo:fscanf 尝试写入未定义的内存地址。

我把它初始化为 char *s = NULL;

是的,指针现在已初始化(耶!),但现在不指向任何地方。

Ergo:fscanf 将尝试写入任何内容。

解决方案是分配一些 fscanf 可以使用的内存。 fscanf 不会神奇地为你分配内存!

您可以使用堆栈内存或动态分配的内存(堆)。

栈内存更容易管理,但比堆小很多。

这里有一个使用栈内存的解决方案:

// Allocates 10 bytes on the stack
// Given 1 Character = 1 Byte the
// buffer can hold up to 9 characters.
char myBuffer[10];

// Initialize s with the address of myBuffer
char *s = myBuffer;

// Call fscanf
fscanf(stream, "%9s", s);

您可能想知道为什么我使用%9s 而不是%s

原因是为了防止缓冲区溢出:

fscanf 不知道缓冲区有多大,所以你需要告诉它。

否则 fscanf 将写入超出分配内存的数据。

我建议您阅读 C 字符串和一般的内存管理。

【讨论】:

  • fscanf(stream, "%9s", s); 没有很好地读取输入的 %s 不保存空白。像"1 2 3" 这样的行不会像"1 2 3" 那样被读入s
  • @chux 仔细观察。不知道:)
【解决方案3】:

您的代码中缺少一些东西。

// Uninitialise pointer, you need to allocate memory dynamically with malloc before you use it. That is
char *s;
int size = 20;  // size of the string you want
s = malloc(size * sizeof(char));

// Or you can use a VLA and with this you don't have to use free(s)

char s[20];


// fopen could fail, always check the return value before using it.
stream = fopen("input.txt", "r"); 

if(stream == NULL){
  perror("File opening failed");
        return EXIT_FAILURE;
}
fscanf(stream, "%s", s);


//Don't forget to do free(s) to free memory allocated with malloc .  when you are done with it

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多