Как сравнить строки в C без жесткого кодирования приращений? - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть буфер, содержащий строку из файла CSV, который я открыл и прочитал. Я разделил строку с помощью strtok() и разделил на ",". Итак, теперь моя строка выглядит следующим образом:

char buff[BUFFER_SIZE] = "1000" "CAP_SETPCAP" "CAP_NET_RAW"

Сейчас я хочу провести сравнение для каждого раздела строки, но на всю жизнь я не могу заставить ее работать. Я хочу быть в состоянии сделать это без жесткого кодирования, что означает, что я не хочу предполагать, сколько пробелов мне нужно переместить. Например, чтобы начать с CAP_SETPCAP, я не хочу ставить buff+5. Кто-нибудь знает лучший способ справиться с этим?

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

#define BUFFER_SIZE 1024

int main(int argc, char *argv[]) {

       FILE *fp = fopen("csvtest.csv", "r");
       char buff[BUFFER_SIZE];


       fgets(buff, 1024, fp);
       char *csvData = strtok(buff, ",");
       while(csvData != NULL){
             csvData = strtok(NULL, ",");
       }

      int i;
      while(buff[i] != '\0'){
         strcmp(buff, "CAP_NET_RAW")
         printf("Match found");
         i++;
      }

      //or I wanted to do string comparison, but I kept getting
      //segmentation fault (core dumped)

      char *found;
      found = strstr(buff, "CAP_NET_RAW");
      printf("%s\n", found);

      fclose(fp);

      return 0;
}

1 Ответ

0 голосов
/ 30 апреля 2020

Ваш код состоит из трех разных разделов. Давайте проанализируем их:


1. Секция strtok

Вы получаете данные из файла и затем выполняете итерацию на strtok:

fgets(buff, 1024, fp);
char *csvData = strtok(buff, ",");
while(csvData != NULL){
    csvData = strtok(NULL, ",");
}

Вам, кажется, не интересно, что вы нашли в разных позициях: в факт csvData всегда перезаписывается последним токеном. И, наконец, оно равно NULL.

Единственное, что вы получите, это запятые в исходном массиве, перезаписанные '\0'. Если вы напечатаете buff, вы увидите только "1000", потому что после этой подстроки находится терминатор строки, помещенный в strtok.


2. Поиск "CAP_NET_RAW"

Теперь вы итерируете buff[i] до конца строки. Но терминатор строки находится после первой подстроки "1000"!

int i;
while(buff[i] != '\0'){
    strcmp(buff, "CAP_NET_RAW")
    printf("Match found");
    i++;
}

Более того, вы ищете CAP_NET_RAW, но даже без проблемы внутренних терминаторов сравнение никогда не будет успешным. Это потому, что (1) строка, фактически присутствующая в баффе, равна "CAP_NET_RAW" (с двойными кавычками); (2) этот токен является последним в ряду, и он будет иметь завершающий '\n' (fgets не удаляет его).

Кстати: I скопировал код после вашего редактирования, и теперь нет проверки strcmp() возвращаемого значения. Я полагаю, это опечатка. Примечание : strcmp возвращает 0, если строка соответствует.


3. strstr попытка

Наконец, вы ищите строку, используя функцию strstr. Это умная идея. Но, как уже говорилось ранее, бафф не содержит его. Ну, буфер действительно содержит его, но строковые утилиты остановятся на первых '\0' найденных ими.

  char *found;
  found = strstr(buff, "CAP_NET_RAW");
  printf("%s\n", found);

Так что found будет NULL и разыменовывает указатель NULL (вот что %s заставляет printf выполнить) приведет к ошибке сегментации.


4. Выводы

В качестве очень простого способа найти единственную строку, о которой вы заботитесь, я предлагаю использовать только strstr, не используя ранее strtok. В качестве альтернативы вы все равно можете использовать strtok, но сохраняете токены в разных строках, чтобы вы могли получить к ним доступ позже.

...