首页 > 解决方案 > Token 忽略String中的一些元素

问题描述

我正在尝试实现一个项目来读取十六进制数并对其进行排序。当我在代码中硬写输入时,代码与我一起正确工作,但是当我修改代码以从文本文件中获取输入时,我得到了不正确的结果,当我调试代码时,我发现令牌没有得到所有的价值观,我不知道为什么。

这是我的代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{


    FILE *in_file  = fopen("input.txt", "r");
    FILE *out_file = fopen("output.txt", "w");


    int bufferLength = 255;
    char buffer[bufferLength];

      if (in_file == NULL)
    {
      printf("Error! Could not open file\n");
      exit(-1);
    }

    char input[] = {};

    fgets(input, bufferLength, in_file);


    int decimal[1000] = {0};

    char * token = strtok(input, " ");
    int n = (int) strtol(token, NULL, 16);
    decimal[0] = n;

    printf("N is : %d , token is : %s \n", n, token);

    int no = 0;
    while(token != NULL) {
      token = strtok(NULL, " ");
      int n = (int) strtol(token, NULL, 16);
      decimal[no+1] = n;
      no++;
      printf("N is : %d , token is : %s \n", n, token);
   }


int temp = 0;

    //Sort the array
    for (int i = 0; i < no; i++) {
        if (decimal[i] == 0){
            break;
        }
        for (int j = i+1; j < no; j++) {
           if(decimal[i] > decimal[j]) {
               temp = decimal[i];
               decimal[i] = decimal[j];
               decimal[j] = temp;
           }
        }
    }



    //Print elements
    for (int j = 0; j < no; j++){
        fprintf(out_file,"%X ", decimal[j]);
    }


    fclose(in_file);
    fclose(out_file);

    return 0;
}

输入是:10 AB 1,但是在调试代码时我得到了以下结果:

N is : 16 , token is : 10
N is : 10 , token is : A

N is : 0 , token is : (null)

标签: ctoken

解决方案


您的代码中基本上存在两个问题:

  1. char input[] = {};声明一个大小为零的数组。当您使用时,fgets(input, ....)您将写入超出此数组的末尾,这将导致未定义的行为。
  2. after token = strtok(NULL, " "),token将是NULL一旦没有更多的标记,然后你在这里取消引用这个 NULL 指针:strtol(token, NULL, 16);

所以你需要改变:

char input[] = {};

char input[bufferLength] = {0};

你需要检查是否strtok返回NULL:

  while (1) {   //<< change this (loop forever)
    token = strtok(NULL, " ");

    if (token == NULL)  // << add this
      break;            // << add this

    int n = (int)strtol(token, NULL, 16);
    decimal[no + 1] = n;
    no++;
    printf("N is : %d , token is : %s \n", n, token);
  }

免责声明:排序部分可能有问题,我没有检查这个。

奖金:

你可以替换这个:

 while (1) {   //<< change this (loop forever)
    token = strtok(NULL, " ");

    if (token == NULL)  // << add this
      break;            // << add this

使用这个更短的代码:

 while ((token = strtok(NULL, " ") != NULL)   
 {

但我不确定这是否适合初学者......


推荐阅读