Почему спецификатор [^] sscanf нарушает мою программу? (C)

#c #string #debugging #scanf #stdio

#c #строка #отладка #scanf #stdio

Вопрос:

Я пытаюсь проанализировать кучу строк с помощью sscanf на c;

Строки форматируются следующим образом: (float) (name) (float)

 example: 
-26.73 Sun 0.000016 
-0.27 Alpha Centauri    4.4 
 

итак, я настроил свой код следующим образом:

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

#define WORD 50
#define PHRASE 150

int main (int argc, char *argv[]){
    char frase [PHRASE 1]= "";
    char star[WORD 1]= "";
    char mom [WORD 1]= "";
    float meg=0, dist=0;
    int ins=0;
    
    FILE *fp;
    
    fp = fopen("stelle.txt", "r");

    if (argc==1){
    }
    
    sscanf(argv[1], "%[1234567890]", mom);
    ins=atoi(mom);
    
        while (fgets(frase, PHRASE, fp)){
            sscanf(frase, "%f %[^ 1234567890] %f", amp;meg, star, amp;dist);
            if (ins==0){
                if ((strcmp(argv[1],star))==0)
                    printf("%g %g", meg, dist);
            }
            
            else {
                if (ins>dist)
                    printf("%g %sn", meg, star);
            }
        }
    
    return 0;
    }
 

Это работает! но иногда имя может состоять из двух слов, и %s действительно может видеть только первое слово, поэтому я должен использовать спецификатор [^] .
итак, я пишу:

     sscanf(phrase, "%f %[^1234567890] %f", amp;meg, star, amp;dist)
 

и этот код буквально ломает программу и приводит к ее сбою, и я не могу точно сказать почему, но если я напишу%[^ 1234567890], он снова заработает, но на самом деле это не решает мою проблему, так что же здесь происходит? в чем проблема?

Комментарии:

1. sscanf это что-то вроде костыля. Почему бы не сканировать первый пробел с strchr помощью , а последний с strrchr помощью , тогда остаток считается именем?

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

3. Было бы полезно, если бы у вас был полный, синтаксически корректный пример здесь. Этого многого не хватает.

4. это для университетского задания, и я ограничен в том, с какими функциями я могу работать, поэтому strchr и strrchr — это не тот вариант, который я могу использовать.

5. @tadman «Вы проверили код возврата из sscanf?» => Я готов поспорить, что 95% проблем, связанных с scanf(), связаны с тем, что программист не проверяет его возвращаемое значение.

Ответ №1:

Существует много того, что кажется диагностическим кодом и другим отладочным мусором, который мешает работе вашей программы. Я очистил его здесь:

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

#define WORD 50
#define PHRASE 150

int main (int argc, char *argv[]) {
  FILE *fp = fopen("stelle.txt", "r");

  if (!fp) {
    // Referencing a NULL pointer later on will result in an immediate crash
    // so this error indicates trouble and exits.
    printf("Could not open filen");

    return -1;
  }

  char line[PHRASE 1];
  while (fgets(line, PHRASE, fp)) {
    char star[WORD 1];
    float meg;
    float dist;

    int srv = sscanf(line, "%f %[^1234567890] %f", amp;meg, star, amp;dist);

    if (srv == 3) {
      printf("%g '%s' %gn", meg, star, dist);
    }
  }

  return 0;
}
 

Это работает для меня на введенных вами данных.