【问题标题】:C - How to compare extended char sequence with function strcmp()?C - 如何将扩展字符序列与函数 strcmp() 进行比较?
【发布时间】:2018-06-13 18:36:15
【问题描述】:

我需要比较字符串是否等于以下扩展字符序列:文本文件中的“———”(ALT + 0151 代码重复三遍)。如何用函数 strcmp() 做到这一点?

示例文本文件 (TSV) 的一段:

皮拉西卡巴大道Armando Salles de Oliveira Lado par 13400-005 Centro 皮拉西卡巴电视。 Agostinho Frasson ——— 13400-008 Centro 皮拉西卡巴大道Armando Salles de Oliveira Lado 位于 13400-010 Centro

当我阅读文件并打印时,显示器上会显示“ùùù”。

结构:

typedef struct {
    char cidade[50];
    char tipoLogradouro[20];
    char logradouro[50];
    char trecho[30];
    char cep[10];
    char bairro[50];
} Endereco;

测试在“switch case”内,程序在这部分崩溃:

case 3:
      {
          if(strcmp(token, "———") == 0) // Change to "ùùù" and fails too. 
              strcpy(registro[i].trecho, NULL);
          else
              strcpy(registro[i].trecho, token);
          break;
      }

非常感谢。

【问题讨论】:

  • 你为什么将NULL 指针传递给strcpy
  • 如果你想在字符串中设置一个空值,使用strcpy(registro[i].trecho, ""); - 使用NULL会导致崩溃。
  • @tadman。对不起。如果值等于“———”我想将“NULL”分配给结构字段,但两者(NULL 或“”)都会使程序崩溃。有什么想法吗?
  • @pelya。我已经尝试过(NULL 或“”)以及任何字符串和程序崩溃。有什么想法吗?
  • 您看到ù 而不是– 的原因是因为您的终端的编码设置与源文件的编码不同。这可能是 Windows-1252 与 ISO-8859-1 编码不兼容。

标签: c char strcmp


【解决方案1】:

通常在 C 中,您只能在带引号的字符串中使用 7 位 ASCII,因此对于高位 ASCII,您需要使用带有字符的十六进制代码的 \x 转义序列。因此,在您的情况下,您可以键入:“\x97\x97\x97”,因为 97 是十六进制的 151 十进制。

case 3:
{
      if(strcmp(token, "\x97\x97\x97") == 0) 
          strcpy(registro[i].trecho, NULL);
      else
          strcpy(registro[i].trecho, token);
      break;
}

【讨论】:

  • 那么,您期望 '—' 出现在执行字符集中,但不在源字符集中?这是可能的,但比源字符集是 ASCII 的可能性更大。
  • @TomBlodget 问题可能出在编辑器的任何地方。在源代码文件中使用 7 位 ASCII 总是最安全的,但就像你说的那样,并不总是必要的。
【解决方案2】:

strcmp 只在 null 上失败,你几乎可以这样做

if (strcmp(inputString,"———")==0){
   printf("Strings Equal\n")
} else{
   printf("Strings unequal")
}

如果您只想查看字符串是否在较大的字符串中,则 strstr 是您要查找的函数,而不是 strcmp。

【讨论】:

  • 谢谢本。我会尝试并稍后发布结果。
  • 如果您无法键入扩展字符,您始终可以使用 \x 转义序列插入带有十六进制代码的字符。因此,在您的情况下,您可以键入:“\x97\x97\x97”,因为 97 是十六进制的 151 十进制。
  • @Ben。我做了更改,但程序崩溃了……我将字符串更改为“ùùù”,也失败了。
  • @bruceg。我将“———”更改为“\x97\x97\x97”,但程序仍然崩溃。 (ALT + 151 与文本文件中的 ALT + 0151 不同)。有什么想法吗?
  • @bruceg。你的建议奏效了!!!我不知道怎么做,但是程序的另一部分中有一行代码,只在运行时出错。现在程序运行完美。你能把你的答案写出来让我把它标记为正确吗?非常感谢。
【解决方案3】:

strcpy 用于一件事和一件事,即将一个字符串复制到另一个字符串。如果你给它NULL,那不是字符串,解引用NULL指针会导致崩溃。

你想要的是这个:

 if (strcmp(token, "———") == 0)
    // Assign NULL pointer
    registro[i].trecho = NULL;
 else
    // Copy string to buffer
    strcpy(registro[i].trecho, token);

记住strcpy 是一个非常冒险的函数,因为它假设了很多关于目标缓冲区的事情。如果trecho 不足以容纳token 字符串,包括 NULL 终止符,你会得到未定义的行为。如果token 未正确以 NULL 终止,则会出现未定义的行为。这个看似无害的代码有很多方法会变得混乱。

【讨论】:

  • 我是 C 语言的“新手”。我尝试了 (NULL 或 "") 和 "\x97\x97\x97" 就像 bruceg 告诉我的那样,甚至任何字符串,程序都不起作用。
  • 尽量不要说“没用”,那真的没有传达任何有用的信息。它会给你一个错误吗?它会崩溃吗?它会产生意想不到的结果吗?我认为您在这里也有编码问题。你能用xxx代替这个非ASCII字符制作一个测试文件吗?除非您的程序和文件中的编码匹配,否则这将无法正确识别令牌。您总是可以像printf("Token: %02x\n", token[0]); 那样进行一些调试,以查看该字符是否为您所期望的 0x97 或其他内容。
  • 请记住,对于这种情况,调试器是一个非常有用的工具。大多数都有直接检查内存并将其显示为十六进制的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-20
  • 2017-12-13
  • 1970-01-01
相关资源
最近更新 更多