【问题标题】:How to get exclude null terminators when reading in a string?读取字符串时如何排除空终止符?
【发布时间】:2015-09-03 07:45:27
【问题描述】:

这个程序打开一个文件,其中包含一个湖的名称和它的体积,以数百立方英里为单位——用空格分隔。它的输出应该是湖泊的名称,后跟多个星号来表示其体积,精确到一百立方英里(例如,体积为 12.70 立方英里的湖泊将打印 13 个星号)。但是,当它读取包含空格的名称时,它会一直读取到空格,然后在新行中打印下一个字符串。例如,有什么方法可以将“gross dirty lake”读为一行而不是“gross\ndirty\nlake”?到目前为止,这是我所拥有的:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void name_asterisks(char name[20], float vol);

main() {
       FILE *fp;
       fp = fopen("lakes.txt", "r");
       char name[20];
       float vol;
       if (fp == NULL) {
          printf("File does not exist.\n");
          system("pause");
          return 0;
       }
       while (fscanf(fp, "%s %f", name, &vol) != EOF) {
             name_asterisks(name, vol);
       }
       fclose(fp);
       system("pause");
}

void name_asterisks(char name[20], float vol) {
     int i;
     printf("%s", name);
     for (i = 0; i < (int)roundf(vol); i++)
         printf("*");
     printf("\n");
}

【问题讨论】:

  • 使用fgets(),然后使用sscanf(buf, " %19[A-Za-z ]%f", name, &amp;vol);
  • 在从你的文件中读取的一行中,湖名是如何与卷号分开的?按空格还是按其他字符?
  • Minor:注意for (i = 0; i &lt; (int)roundf(vol); ...重复计算roundf(vol)。建议int n = (int) roundf(vol); for (i = 0; i &lt; n; ...

标签: c string file-io


【解决方案1】:

"%s" 用于扫描非空白。代码需要不同的格式说明符。

char buf[100];
while (fgets(buf, sizeof buf, fp) != NULL) {
   if (sscanf(buf, " %19[A-Za-z ]%f", name, &vol) != 2) {
     fprintf(stderr, "Unexpected data\n");
     break;
   }
   name_asterisks(name, vol);
 }

" ":跳过空格。
"%19[A-Za-z ]":扫描并保存最多 19 个字母或空格,追加 '\0'
"%f":跳过空格并保存扫描 @ 987654327@.

关于原始代码的注意事项:最好检查代码想要什么而不是检查 1 个不想要的结果

// while (fscanf(fp, "%s %f", name, &vol) != EOF) {
while (fscanf(fp, "%s %f", name, &vol) == 2) {

【讨论】:

    【解决方案2】:

    gross dirty lake 12.7\n 的样例

    #include <string.h>  //for strrchr
    ...
    char line[64];//line buffer
    ...
    while (fgets(line, sizeof line, fp)){
        char *p = strrchr(line, ' ');//search last ' '
        *p = '\0';
        //snprintf(name, sizeof(name), "%s", line);
        vol = atof(p+1);
        name_asterisks(line, vol);//name_asterisks(name, vol);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-26
      相关资源
      最近更新 更多