【问题标题】:strcmp() and New Line Characters from Text File文本文件中的 strcmp() 和换行符
【发布时间】:2012-10-28 03:17:40
【问题描述】:

我正在尝试使用strcmp() 来测试文本文件中的特定行是否等于换行符(\n)。我从一个文本文件中收集每一行,并将它们写入另一个文本文件。如果源文件中的整行只是一个换行符,我不想在目标文件中写入该行。

我认为下面的代码可以用于此目的,但事实并非如此。但是,如果我将条件中的数值从 0 更改为 3,它就像我希望它工作一样工作。知道为什么吗?

我的目标是更改条件,使其使用数值 0,这意味着 strcmp() 找到完全匹配,但我不知道如何更改条件的其他部分来做到这一点。

#include <stdio.h>

void process_file(const char *inp_file, FILE *otp_fp) {

  char line[256];
  FILE *inp_fp = fopen(inp_file, "r");

  if (inp_fp != NULL) {
    while(fgets(line, 256, inp_fp) != NULL) {

      if (strcmp (line, "\n") != 0) { //changing to 3 gets desired result
        fprintf(otp_fp, line);
      }

    }
  }

  fclose(inp_fp);

}

【问题讨论】:

  • 这对我有用。还有其他可能的错误吗?
  • 你确定你的行不是以 CRLF 结尾而不是普通的 LF 结尾吗?试试 strcmp(line, "\r\n")
  • "\r\n" 正如您所建议的那样有效。谢谢。我想知道为什么它以原始形式适用于 squiguy。我会进一步研究。
  • @nairware 我使用 Linux 运行它,其中 \n 是行尾。您必须使用 \r\n 是行尾的 Windows。
  • 如果您在 Windows 上,该文件将作为文本文件打开(因为该模式下没有 b),因此 CRLF 将在输入时映射到 NL。如果将文件作为二进制文件从 Windows 复制到 Unix(包括 Mac),则 CRLF 结尾保持不变。如果您使用 FTP 并指定文本 (ASCII) 模式传输,则 CRLF 结尾将再次固定。您必须做出决定;当您的程序在 Unix 上运行时,您是否希望您的程序能够处理源自 Windows 的文件?如果是这样,那么您需要比较两个行尾;如果没有,请选择您当地的结局。

标签: c newline strcmp


【解决方案1】:

您描述的行为的唯一解释是这些行并不是真正的空行。它们必须有一些空格(如空格或制表符)。如果你想省略这些行,那么你必须检查它们是否真的只包含空格。

(我还修复了您代码中的一个问题,如果fopen() 失败,您将尝试fclose() NULL 指针。这也演示了如何通过仅在出错后运行代码来降低函数的缩进级别条件已处理。)

int str_is_whitespace(const char* line) {
    int onlyws = 1;
    int i = 0;
    while (onlyws && line[i] != '\0') {
        if (!isspace(line[i])) {
            onlyws = 0;
        }
        ++i;
    }
    return onlyws;
}

void process_file(const char *inp_file, FILE *otp_fp) {
    char line[256];
    FILE *inp_fp = fopen(inp_file, "r");
    if (inp_fp == NULL) {
        return;
    }
    while(fgets(line, 256, inp_fp) != NULL) {
        // Only output the text if it doesn't consist only of whitespace.
        if (!str_is_whitespace(line)) {
            fprintf(otp_fp, "%s", line);
        }
    }
    fclose(inp_fp);
}

您需要为isspace() 包含&lt;ctype.h&gt;

请注意,如果行长度超过 255 个字符,您会遇到麻烦,而fgets() 碰巧读取了一行中只有空格的剩余部分。如果你想解决这个问题,你需要额外的逻辑来确定当前文本是否实际上是更大行的一部分。

【讨论】:

    【解决方案2】:
    #include <stdio.h>
    #include <string.h>
    
    void process_file(const char *inp_file, FILE *otp_fp) {
    
      char line[256];
      FILE *inp_fp ;
      size_t len;
    
      inp_fp = fopen(inp_file, "r");
    
      if (!inp_fp ) return;
    
      while(fgets(line, 256, inp_fp) != NULL) {
        len = strlen(line);
            /* skip trailing space */
        while (len && (line[len-1] == '\n' || line[len-1] == '\r')) {line[--len] = 0;}
    
        if (!len ) continue;
            /* dont use random strings as format argument for printf() et.al.
            ** (there could be '%' signs in it) 
            ** Note: the \r\n (if any) were removed, and now are re-added.
            ** This will impose the line-ending convention that the current platform uses.
            */
        fprintf(otp_fp, "%s\n", line);
    
      }
    
      fclose(inp_fp);
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-26
      • 2017-02-28
      • 2019-08-31
      • 2020-05-24
      相关资源
      最近更新 更多