【问题标题】:Iterate through every char in string stored in an array遍历存储在数组中的字符串中的每个字符
【发布时间】:2023-04-07 09:53:02
【问题描述】:

我在大学的前半年对 C 语言非常陌生。这是我在 StackOverflow 上的第一个问题。

我的任务是对其进行编程,以便将存储在数字中的每个字符串转换为十进制,而无需更改主函数之外的任何内容。

我现在正在尝试过去 4 个小时来解决这个问题,我想根据与长度相比的位置来迭代我当前到的字符串中的每个字符,以将其转换为小数。

我唯一的问题是有人帮助我了解如何在不使用 strlen() 的情况下获取字符串长度,因为我无法添加 #include <string.h>

这是我到目前为止得到的(获取数组的长度以遍历每个索引):

#include <stdio.h>

#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm

int main() {
    char* numbers[] = {
        "01001001",
        "00101010",
        "010100111001",
        "011111110100101010010111",
        "0001010110011010101111101111010101110110",
        "01011100110000001101"};
    
    // Add here..
    
    int length = sizeof(numbers);
    
    

    for ( int i = 0; i < length; i++ ){
        
         //how do i get the string size without strlen() D:
            
        }
        
    
    
    return 0;
}

【问题讨论】:

  • 您了解strlen 的工作原理,或者一般来说,是什么决定了C 中字符串的长度吗?
  • 我想我知道 strlen() 是如何工作的,但在这种情况下我不能用它来确定当前字符串的实际大小
  • 注意:strlen() 的签名是size_t strlen(const char *s);,但不需要strlen() 来停止for 循环。只需查找 null 字符
  • sizeof 返回保存其参数所需的字节数,这不是您想要的 length

标签: c string iterator


【解决方案1】:

这个项目可以在不计算字符串长度的情况下完成。如何?在 C 中,所有字符串都是 nul-terminated,在组成字符串的最后一个字符之后包含 nul-character '\0'(ASCII 值 0)。当您需要遍历一个字符串时,您只需循环直到字符值为0(例如 nul-character

这就是所有字符串函数知道何时停止读取字符的方式。由于您有一个包含字符串的 指针数组,因此您只需要遍历每个指针,并且对于每个指针,遍历每个字符,直到找到 nul 字符。

总而言之,(并注意您不需要math.h),您可以这样做:

#include <stdio.h>

#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm

int main() {
    char* numbers[] = {
        "01001001",
        "00101010",
        "010100111001",
        "011111110100101010010111",
        "0001010110011010101111101111010101110110",
        "01011100110000001101"};
    
    int nnumbers = sizeof numbers / sizeof *numbers;    /* no. of elements */
    
    for (int i = 0; i < nnumbers; i++) {
        long long unsigned number = 0;
        /* you don't care about the length, strings are nul-terminated,
         * just loop until \0 is found.
         */
        for (int j = 0; numbers[i][j]; j++) {
            number <<= 1;                               /* shift left */
            number += numbers[i][j] == '1' ? 1 : 0;     /* add bit */
        }
        
        printf ("%s = %llu\n", numbers[i], number);     /* output result */
    }
    return 0;
}

注意:您必须使用 64 位类型来保存转换后的值,因为 "1010110011010101111101111010101110110" 需要最少 38 位来表示)

使用/输出示例

将每个字符串转换为数值的简单示例输出:

$ ./bin/binstr2num
01001001 = 73
00101010 = 42
010100111001 = 1337
011111110100101010010111 = 8342167
0001010110011010101111101111010101110110 = 92790519158
01011100110000001101 = 379917

【讨论】:

    【解决方案2】:

    在 C 中,字符串实际上只是 char 数组,带有一个特殊的终止符来标记字符串的结尾。所以,假设你有类似的东西:

    char *str = "hello";
    

    这基本上等同于:

    char str[] = {'h', 'e', 'l', 'l', 'o', '\0'};
    

    注意到数组末尾的\0 字符了吗?这是 C 放在字符串末尾的特殊终止符。像strlen() 这样的函数几乎会遍历char 数组,寻找\0 字符的第一次出现然后停止。

    所以,您可以制作自己的strlen() 版本,比如my_strlen()

    int my_strlen(char *str)
    {
        /* Initialize len to 0 */
        int len = 0;
        
        /* Iterate through str, increment len, and stop when we reach '\0' */
        while(str[len] != '\0')
            len++;
        
        /* Return the len */
        return len;
    }
    

    然后在你的for 循环中,你可以调用这个函数。另外,请注意您对numbers 数组大小的计算:

    int length = sizeof(numbers);
    

    不会给你数组中元素的数量。该代码为您提供大小(以字节为单位)或numbers,它是char 指针的数组。如果要获取元素的数量,则必须将该大小除以单个元素的大小(以字节为单位)(即char 指针)。所以,这样的事情会起作用:

    int length = sizeof(numbers) / sizeof(numbers[0]);
    

    您的最终代码可能如下所示:

    #include <stdio.h>
    
    #include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
    
    int my_strlen(char *str) {
        /* Initialize len to 0 */
        int len = 0;
        
        /* Iterate through str, increment len, and stop when we reach '\0' */
        while(str[len] != '\0')
            len++;
        
        /* Return the len */
        return len;
    }
    
    int main() {
        char* numbers[] = {
            "01001001",
            "00101010",
            "010100111001",
            "011111110100101010010111",
            "0001010110011010101111101111010101110110",
            "01011100110000001101"};
        
        // Add here..
        
        // Notice the change here
        int length = sizeof(numbers) / sizeof(numbers[0]);
        
        
        for(int i = 0; i < length; i++ ){
            int str_len = my_strlen(numbers[i]);
            // Do what you need with str_len            
        }
            
        
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      你可以用这个函数代替strlen()

      int strlen_my(char *str){
          int len=0;
          for(;str[len]!='\0';len++){}
          return len;
      }
      

      strlen_my("hello, world!");一样使用它

      【讨论】:

        【解决方案4】:
        #include <stdio.h>
        int main(){
        
            char arr[20]="Hello";
            int count=0;
           
            while(arr[count]!='\0'){
                count++;
            }
            printf("%d",count);
        
            return 0;
        }
        
        

        看看这个小代码,你就明白了。在 C 中,字符串以 NULL 字符结尾。我们可以利用这个优势。

        【讨论】:

          【解决方案5】:

          有几种方法可以做到这一点。 IMO,一个简单、合理的实现strlen的方法是:

          size_t string_length(const char *s)  { return strchr(s, '\0') - s; } 
          

          但如果您不允许使用strlen,那么您可能也不允许使用strchr。所以你只需要数数。对于一个完整的初学者来说,最惯用的方法可能有点晦涩,所以这里有一个更详细的方法。

          请注意,您对数组中元素数量的计算无效,已在下面进行了更正。

          #include <stdio.h>
          
          int
          length(const char *s)
          {
                  int len = 0;
                  while( *s++ ){
                          len += 1;
                  }
                  return len;
          }
          
          int
          main(void)
          {
                  char *numbers[] = {
                          "01001001",
                          "00101010",
                          "010100111001",
                          "011111110100101010010111",
                          "0001010110011010101111101111010101110110",
                          "01011100110000001101"
                  };
                  int count = sizeof numbers / sizeof *numbers; /* Number of entries */
          
                  for( int i = 0; i < count; i++ ){
                          printf(" length of %s is %d\n", numbers[i], length(numbers[i]));
                  }
                  return 0;
          }
          

          这是相当主观的,但 IMO 更惯用的写法是:

          #include <stdio.h>
          
          int
          length(const char *e)
          {
                  const char *s = e;
                  while( *e++ )
                          ;
                  return e - s - 1;
          }
          
          int
          main(void)
          {
                  char *numbers[] = {
                          "01001001",
                          "00101010",
                          "010100111001",
                          "011111110100101010010111",
                          "0001010110011010101111101111010101110110",
                          "01011100110000001101"
                  };
                  char **e = numbers + sizeof numbers / sizeof *numbers;
                  for( char **t = numbers; t < e; t++ ){
                          printf(" length of %s is %d\n", *t, length(*t));
                  }
                  return 0;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-09-09
            • 2021-01-11
            • 1970-01-01
            • 2011-08-07
            • 2021-12-10
            • 2011-10-06
            • 1970-01-01
            相关资源
            最近更新 更多