【问题标题】:C - storing user input in a dynamic char array?C - 将用户输入存储在动态字符数组中?
【发布时间】:2016-11-04 10:50:39
【问题描述】:

我想从用户那里读取一些字符串输入并将其写入文件。现在我在做

char name[25];
scanf("%s", name);
int handle = open("./visitors.txt", O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
if (handle < 0){
   printf("File error.\n");
   return;
}
lseek(handle, -sizeof(name), SEEK_END);
write(handle, name, sizeof(name));

这当然是不对的,因为大多数时候用户不会写 25 个字符,只有更少,所以当用户输入 5 个字符时,其他 20 个将是空的,我最终有 5 个字符用户在我的输出文件中输入和 20 个字符乱码。如何确保仅将用户输入写入文件?

【问题讨论】:

  • 通过阅读scanf的手册? %s 导致输出为空终止。
  • -sizeof(name) 应该是 -(off_t)sizeof(name)
  • @M.M 没有任何区别。

标签: c file


【解决方案1】:

您正在使用原始系统调用来处理文件操作。除非您的意图是专门了解系统调用,否则您不应该这样做。 The write call 写入由第三个参数指定的字节数。 sizeof(name) 在这种情况下是错误的。它不会返回字符串的长度,而是返回整个缓冲区的长度。

标准strlen function 为您提供字符串长度。因此,如果用户输入 5 个字符,运行 strlen(name) 将为您提供 5 个字符,这与您正在使用的 sizeof 不同。

除非您想专门了解系统调用,否则您可能应该使用 C 标准库处理文件操作,使用fprintf 输出到文件,以及诸如fopenfclose 之类的函数。看看at the fprintf docs,它也链接到其他功能。

【讨论】:

  • 就是这样!使用 strlen() 而不是 sizeof() 修复了它。谢谢!
【解决方案2】:

我不确定您要使用低级系统调用openlseekwrite 的原因。通常使用标准 C fopenfscanffprintf 函数来完成此类任务要方便得多。

在这种情况下,您可以尝试fgetsstdin 获取字符串输入,然后使用fprintf%s 写入文件。您仍然可以使用缓冲区name[25]name[100](设想来自stdin 的最大输入)。只需正确初始化它以确保它以 NULL 终止。然后fprintf%s 会将字符串正确地写入文件(即没有乱码结尾)。

【讨论】:

  • 如何确保缓冲区为空终止?
  • 初始化char name[25] = "";
  • 如果你需要在循环中使用name,那么memset在循环开始的时候就全部为零
  • 我不确定您要使用低级系统调用openlseekwrite 的原因。 性能?控制?灵活性?减少依赖?学习?
  • @artm 尝试使用fread()/fwrite()从随机文件偏移量进行无锁原子读/写操作
猜你喜欢
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-03
  • 1970-01-01
  • 2017-09-12
相关资源
最近更新 更多