Сравните количество каждой строки в файле

Я начал изучать C, переменные, функции, память и структуры были в порядке, но теперь я застрял на очень простых упражнениях с файлами.

Пример

У меня есть файл с именем и оценкой в ​​каждой строке. Что-то вроде

asdfgh 1.5
asdfg h 2
a 0.5

Я научился читать каждую строку и могу написать программу, которая считывает каждую строку и выводит количество строк и т. д., но сейчас я хочу научиться изолировать числа, чтобы сравнивать их позже. Например, чтобы получить максимум или среднее значение, это не имеет значения. Что-то вроде

The max number is 2

Я использую fgets и sscanf, но на данный момент я очень запутался во всех учебниках, которые я уже смотрел.

Любой простой пример или учебник, которым можно поделиться?

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

Я могу открыть файл, прочитать файл и прочитать каждую строку до конца файла, но сохранение символов с числами в нем, чтобы позже сравнить их, - это та часть, которую я не получаю

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

char name[1000];
float number = 0;
int lines = 0;
char line[1000];

do {
    fgets(line, 1000, stdin);
    lines++
} while (line[0] != '\n');

return 0;

Пожалуйста, используйте идиоматику while(fgets(line, 1000, stdin) != NULL). Тест на line[0] может никогда не быть '\n'.

Weather Vane 07.01.2023 19:12

Если число всегда находится в последней позиции и за ним не следуют пробелы, вы можете использовать strrchr(), чтобы найти его начало, а затем atof() или strtod(), чтобы преобразовать строку в число.

DYZ 07.01.2023 19:14

Ваш код неполный, плюс он на самом деле не использует sscanf. Было бы полезно иметь ваш фактический код и объяснение того, какие конкретные проблемы у вас возникают с ним.

jarmod 07.01.2023 19:14

Если число действительно может быть любым токеном в строке, используйте fgets, чтобы получить строку. Затем зациклитесь на strtok(...," \t\n") и посмотрите на первый символ токена. Если это цифра (например, isdigit), то расшифруйте ее с помощью strtol.

Craig Estey 07.01.2023 19:16

В сторону: пожалуйста, не превращайте этот вопрос в «зыбучий песок» в ответ на комментарии. Опубликуйте фактический код, который вы использовали, а не догадки. Я имел в виду while, а не do...while.

Weather Vane 07.01.2023 19:17

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

Throwaway 07.01.2023 19:19
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать strcspn, чтобы найти первую цифру.

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

int main(void) {
    char s[] = "hello world 123";
    size_t n = strcspn(s, "1234567890");

    printf("%s\n", &s[n]);

    return 0;
}

Отпечатки:

123

Если у нас есть указатель на эту подстроку, мы можем использовать strtod, чтобы преобразовать ее в double.

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

int main(void) {
    char s[] = "hello world 123";
    size_t n = strcspn(s, "1234567890");

    printf("%lf\n", strtod(&s[n], NULL));

    return 0;
}

Отпечатки:

123

Конечно, вам, вероятно, также следует проверить ошибки, чтобы определить, была ли найдена числовая цифра.

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

int main(void) {
    char s[] = "hello world";
    size_t n = strcspn(s, "1234567890");

    if (!s[n]) {
        printf("Numeric digit not found.\n");
        return 1;
    }

    printf("%lf\n", strtod(&s[n], NULL));

    return 0;
}

Спасибо. Я собираюсь изучить это, так как я не знал о strtol() или strtod(), но это простой и понятный код. Я думаю, что могу «поиграть» с этим, чтобы узнать больше о файлах. Спасибо :)

Throwaway 07.01.2023 19:23

Крис, рассмотрите такие входные данные, как ".123", "-456". Этот ответ сообщает 123 и 456.

chux - Reinstate Monica 07.01.2023 22:37

Я согласен. Ваше решение более надежное. Тем не менее, я думаю, что ответ, который я дал, может иметь некоторую ценность, поэтому не буду его удалять. УФ для вас, однако.

Chris 07.01.2023 22:41
Ответ принят как подходящий

Числа могут начинаться с '0'-'9', '+', '-', '.', 'I', 'i' (бесконечность), 'N', 'n' (NAN), пробелов и других значений, специфичных для реализации, таких как ','. Возможно, даже ` в будущем. *1

Вместо того, чтобы искать только первый числовой символ, используйте strtod() несколько раз и позвольте этой функции проверить текст как число.

const char *s = line;
char *endptr;  // Location to store end of conversion.
bool found = false;
double d;
for (; *s; s++) {
  errno = 0;
  d = strtod(s, &endptr);
  if (s == endptr) continue;  // No conversion.
  // If following is not a space nor a null character ...
  if (!isspace((unsigned char) *endptr) && *endptr) continue;
  // You may want to test for range or skip this.
  if (errno == ERANGE) continue;
  found = true;
  break;
}
if (found) {
  printf("Found %g at <%.*s>\n", d, (int)(endptr - s), s);
}

*1 В следующей версии языка C могут быть добавлены новые функции, такие как разделитель цифр ', двоичный ввод и т. д. Используя стандартные функции для проверки, ваш код готов к будущему — это сокращает объем обслуживания и поддерживает актуальность кода.

Другие вопросы по теме