2016-11-11 53 views
3

,所以我必须拥有渠道的名称的文本文件,格式如下:如何加入字符数组在C

General 
Private 
Programming 
Calculus 

而我正在试图做的是,如果用户写了“/渠道“控制台上的程序应该打印在这种格式的所有通道:

Channels are : General, Private, Programming, Calculus 

我的问题是印刷在这种格式的渠道,用逗号分隔。使用我现在可以打印的通道,但是它们以文本文件中的格式打印(每行一个通道名称)。如果有人能够向我解释做这件事的最佳方式是什么,我会非常感激。下面是代码我现在有打印频道:

void get_channels() { 
    char tmp[50]; 
    FILE *f; 
    f = fopen("../1part/channels.txt", "r"); 
    if (f == NULL) { perror("Mistake reading: "); exit(1); } ; 
    while (fgets(tmp, sizeof(tmp), f)) { 
     printf("%s", tmp); 
    } 

    fclose(f); 
} 

回答

3

你应该剥去由fgets()读取的行结尾的换行。

void get_channels(void) { 
    char tmp[50]; 
    FILE *f; 
    const char *separator = ""; 

    f = fopen("../1part/channels.txt", "r"); 
    if (f == NULL) { 
     perror("Mistake reading: "); 
     exit(1); 
    } 
    printf("Channels are: "); 
    while (fgets(tmp, sizeof(tmp), f)) { 
     /* strip the newline character if present */ 
     tmp[strcspn(tmp, "\n")] = '\0'; 
     printf("%s%s", separator, tmp); 
     separator = ", "; 
    } 
    printf("\n"); 

    fclose(f); 
} 

注:

  • 如果文件不以回车结束,除去该行的最后一个字符将无法正常工作。
  • 如果文件中的一行超过49个字符,则tmp也不会以换行结束。剥离最后一个字符也是不正确的,但是上面的代码仍然会错误地处理这种情况,因为这样的一行会被分成两个项目。增大缓冲区是一个简单的解决方案。
  • separator在每个项目之前输出字符串,将其初始化为空字符串,并在每个项目之后将其更改为", ",这是在没有额外测试的情况下生成联合列表的简单方法。
+0

对于这种'分隔符',我们避免了每个项目的测试,但我们是一个任务,反正更好? – aurox

+0

任务通常比测试便宜很多,因为它不会导致分支。不同的处理器的行为有所不同,只有仔细的基准测试才能证明一种方法比另一种处理器和目标环境组合的效率更高。 – chqrlie

1

我的问题是打印通道以这种格式,用逗号分隔。

您可能希望从fgets删除\n - 这样你可以在一行printf几项:

while (fgets(tmp, sizeof(tmp), f)) 
{ 
    tmp[strlen(tmp) - 1] = '\0'; // remove \n 
    printf("%s, ", tmp); 
} 
+0

是的,我知道如何删除输入,但我的问题是插入逗号后。 – GamerGirl

+0

这会在最后留下多余的逗号。 – Groo

+0

是的,我知道我可以而不是删除输入替换char','但是像你说的那样,它总是在最后留下一个逗号。 – GamerGirl

相关问题