Как преобразовать строковое значение в числовое значение? - PullRequest
0 голосов
/ 09 декабря 2018

Я пробовал этот код, чтобы разделить мою строку Str [] на 2 строки, но моя проблема заключается в том, что «я хочу разделить Джона (имя) как строку и 100 (метки) как целое число», как я могу это сделать, любойпредложение?

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

    void main()
    {
        char Str[] = "John,100";
        int i, j, xchange;
        char name[50];
        char marks[10];
        j = 0; xchange = 0;

        for(i=0; Str[i]!='\0'; i++){
            if(Str[i]!=',' && xchange!=-1){
                name[i] = Str[i];
            }else{
                xchange = -1;
            }
            if(xchange==-1){
                marks[j++] = Str[i+1];
            }
        }
        printf("Student name is %s\n", name);
        printf("Student marks is %s", marks);
    }

1 Ответ

0 голосов
/ 09 декабря 2018

Как разделить "Джон, 100" на 2 строки?

Существует три общих подхода:

  1. Использование strtok(), чтобы разбить строку на отдельные токены.Это изменит исходную строку, но ее довольно просто реализовать:

    int main(void)
    {
        char  line[] = "John,100;passed";
        char *name, *score, *status;
    
        /* Detach the initial part of the line,
           up to the first comma, and set name
           to point to that part. */
        name = strtok(line, ",");
    
        /* Detach the next part of the line,
           up to the next comma or semicolon,
           setting score to point to that part. */
        score = strtok(NULL, ",;");
    
        /* Detach the final part of the line,
           setting status to point to it. */
        status = strtok(NULL, "");
    

    Обратите внимание, что если вы измените char line[] = "John,100";, тогда status будет NULL, но код в противном случае безопасен для запуска.

    Итак, на практике, если требуется , чтобы все три поля существовали в line, было бы достаточно убедиться, что последнее не было NULL:

        if (!status) {
            fprintf(stderr, "line[] did not have three fields!\n");
            return EXIT_FAILURE;
        }
    
  2. Используйте sscanf() для преобразования строки.Например,

        char  line[] = "John,100";
        char  name[20];
        int   score;
    
        if (sscanf(line, "%19[^,],%d", name, &score) != 2) {
            fprintf(stderr, "Cannot parse line[] correctly.\n");
            return EXIT_FAILURE;
        }
    

    Здесь 19 относится к числу символов в name (один всегда зарезервирован для nul char в конце строки, '\0') и [^,] - это преобразование строк, потребляющее все, кроме запятой.%d конвертирует int.Возвращаемое значение - это число успешных преобразований.

    Этот подход не изменяет исходную строку и позволяет попробовать несколько различных шаблонов синтаксического анализа;если сначала вы попробуете их как можно более сложными, вы можете использовать несколько форматов ввода с небольшим количеством добавленного кода.Я делаю это регулярно, когда принимаю 2D или 3D векторы в качестве входных данных.

    Недостатком является то, что sscanf() (все функции семейства scanf) игнорирует переполнение.Например, в 32-разрядных архитектурах наибольшее значение int равно 2147483647, но функции scanf будут успешно преобразовывать, например, 9999999999 в 1410065407 (или какое-либо другое значение!), Не возвращая ошибку.Вы можете только предполагать, что числовые данные вменяются и находятся в определенных пределах;вы не можете проверить.

  3. Используйте вспомогательные функции для токенизации и / или анализа строки.

    Как правило, вспомогательные функции имеют вид, подобный

    char *parse_string(char *source, char **to);
    char *parse_long(char *source, long *to);
    

    где source - указатель на следующий символ в анализируемой строке, а to - указатель, где будет сохранено проанализированное значение;или

    char *next_string(char **source);
    long  next_long(char **source);
    

    , где source - указатель на указатель на следующий символ в анализируемой строке, а возвращаемое значение - это значение извлеченного токена.

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


Если данные представляют собой какой-то вариант CSV (значения, разделенные запятыми) читаются из файла, тогда правильный подход другой: вместо того, чтобы читать файл построчно, вы читаете токен файла по токену.

Единственный "трюк"запомнить символ разделителя, который завершил токен (для этого можно использовать ungetc()), и использовать другую функцию для (чтения и игнорирования остальных токенов в текущей записи и) использования разделителя новой строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...