【问题标题】:How to get the length of a string in c, if it has integers in itc - 如果字符串中有整数,如何获取字符串的长度
【发布时间】:2017-09-15 14:45:33
【问题描述】:

我熟悉 C 中的 sizeof 操作,但是当我将它用于字符串 "1234abcd" 时,它只返回 4,我假设它占最后 4 个字符。 那么我怎样才能让它成为一个大小为 8 的字符串呢?

具体代码如下:

FILE *in_file;
in_file = fopen(filename, "r");     
if (in_file == NULL) {
    printf("File does not exist\n");
    return 1;
}

int val_to_inspect = 0;

fscanf(in_file, "%x", &val_to_inspect);

while (val_to_inspect != 0) {
    printf("%x", val_to_inspect);
    int length = sizeof val_to_inspect;
    printf("%d", length);

再次说明,从文件中读取的字符串是"1234abcd"

【问题讨论】:

  • sizeof 将为您提供数据类型的大小。查看strlen()
  • int len1 = 0, len2 = 0; fscanf(in_file," %n%x%n", &len1, &val_to_inspect, &len2); int length = len2 - len1;

标签: c string sizeof


【解决方案1】:

这里有几个问题:

sizeof 运算符返回对象的大小。在这种情况下,它返回val_to_inspect 的大小,即inthttp://en.cppreference.com/w/cpp/language/sizeof

fscanf 从流中读取并解释它。您只扫描一个整数 ("%x"),而不是一个字符串。 http://en.cppreference.com/w/cpp/io/c/fscanf

最后,如果你真的有一个以 nil 结尾的字符串,你可以使用 strlen() 来获取它的长度。

【讨论】:

  • 更准确地说,要得到一个以null结尾的字符串的长度,不仅可以一个使用strlen(),一个应该 这样做。应用于char *char 数组的sizeof 运算符计算不同的东西(并且在这两种情况下不同)。
  • 从未声称 sizeof 有可能是这项工作的工具 :)
  • 不,我提到 sizeof 因为 OP 正在使用它。我的评论是关于您选择的措辞;我已经澄清了。
  • 您可以使用 strlen,您可以将 c-string 输入到 std::string。你可以做很多事情,这取决于它来自哪里以及你打算用它做什么。
【解决方案2】:

TL;DR,要获取字符串的长度,需要使用strlen()

也就是说,在使用sizeof 时要小心一点,它对数据类型进行操作。因此,如果您将指针传递给它,它将返回指针变量的大小,而不是它指向的 string 的长度。

【讨论】:

    【解决方案3】:

    在几个重要的方面,只有其中一些与sizeof 有任何关系,你对你的代码实际上做了什么是错误的。

    FILE *in_file;
    in_file = fopen(filename, "r");     
    if (in_file == NULL)
      {
        printf("File does not exist\n");
        return 1;
      }
    

    感谢实际检查fopen 是否成功;很多人在开始使用 C 语言时忘记这样做。但是,fopen 可能失败的原因有很多;不存在的文件只是其中之一。每当 I/O 操作失败时,请务必打印 strerror(errno),以便了解实际原因。此外,错误消息应发送至stderr,而不是stdout,并应包括受影响文件的名称(如果有)。更正后的代码看起来像

    if (in_file == NULL)
      {
        fprintf(stderr, "Error opening %s: %s\n", filename, strerror(errno));
        return 1;
      }
    

    (如果string.herrno.h 不存在,则需要将它们添加到文件顶部。)

    int val_to_inspect = 0;
    fscanf(in_file,"%x", &val_to_inspect);
    

    这段代码从文件中读取字符串。它跳过任何前导空格,然后从文件中读取一系列十六进制数字,一旦遇到非数字就停止,并立即将它们转换为存储在val_to_expect 中的机器编号。对于包含1234abcd 的文件,它确实会从文件中读取八个字符,但对于其他文件内容,它可能会读取更多或更少。

    (从技术上讲,使用 %x 转换说明符,您应该使用 unsigned int,但大多数实现都会让您摆脱使用带符号的 int。)

    (当您在 C 语言中进行更多练习时,您会发现 scanf 已被破坏,并且很难稳健地使用,但现在不用担心。)

    while (val_to_inspect != 0) {
        printf("%x", val_to_inspect);
        int length = sizeof val_to_inspect;
        printf("%d", length);
    }
    

    您没有将sizeof 应用于字符串,而是将其应用于int。在您的计算机上,int 的大小是 4 chars,这是真的无论值是多少

    此外,sizeof 应用于实际的 C 字符串(即,char * 变量指向以 NUL 结尾的字符序列)计算字符串的长度。相反,它将告诉您 pointer 指向字符串的大小,该大小将是一个与字符串长度无关的常数(通常为 4 或 8,具体取决于计算机)。要计算字符串的长度,请使用库函数strlen(在string.h 中声明)。

    您有时会看到巧妙的代码将sizeof 应用于字符串文字,它确实返回了一个与其长度相关(但不等于!)的数字。为您练习:弄清楚这个数字是多少,以及为什么sizeof 对字符串文字执行此操作,而不是对一般字符串执行此操作。 (提示:当s 被声明为char s[] = "string"; 时,sizeof s 将返回一个与s 的字符串长度相关的数字,但在声明为char *s = "string";不会。)

    最后一点,无论您是否喜欢将左大括号放在自己的行中,这在总体方案中并不重要,但选择一种风格并在整个文件中坚持下去。不要将一些 if 左大括号放在自己的行中,而将其他大括号放在 if 行的末尾。

    【讨论】:

    • 我会说:int 在您的计算机上的大小是 4 字节...
    • @chqrlie byte 不一定与 char 大小相同。 sizeofchar 单位定义。 (是的,这太迂腐了,但我之前曾在这个网站上因为掩饰区别而被大喊大叫,所以。)
    • 恐怕你不正确。根据定义,C 和 C++ 中的 char 类型是最小的可寻址单元,大小为 1。它正好是一个字节。反之,字节不一定有 8 位,旧系统曾经有 9 位字节,有些 DSP 处理器有 16 位甚至 32 位字节。我坚持使用 byte 这个词的原因是因为char 类型附加了特定的语义,例如潜在的符号,这与对象的大小无关。 OTOH char 在 Java 中的类型是 16 位,在大多数系统上需要 2 个字节。
    • C 标准这样定义sizeof 的值:6.5.3.4 sizeof_Alignof 运算符 [.. .] sizeof 运算符产生其操作数的大小(以字节为单位)...
    【解决方案4】:

    最好创建自己的计数器,通过逐个字符读取来查找"1234abcd" 的长度。

    FILE *in_file;
    char ch;
    int length=0;
    
    in_file = fopen("filename.txt", "r");
    if (in_file == NULL)
    {
        printf("File does not exist\n");
        return 1;
    }
    while (1) {
        ch = fgetc(in_file);
        printf("%c", ch);
        if (ch == EOF)
            break;
        length++;
    }
    fclose(in_file);
    printf ("\n%d",length);
    

    【讨论】:

      【解决方案5】:

      各位,感谢大家的反馈。我意识到我在原始帖子中犯了很多错误,但我只是从 c++ 切换到 c,所以我习惯的很多东西不能真正以同样的方式应用。这一切都非常有帮助,有地方可去真是太好了。

      【讨论】:

        【解决方案6】:

        Len=sizeof(你的字符串)/sizeof(char)-1 -1 是 eof 字符 null 如果您想从特定的起始索引中获取任何长度,只需执行 Len-index

        【讨论】:

          猜你喜欢
          • 2011-05-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多