Установка строки в пустую строку в C - PullRequest
0 голосов
/ 08 апреля 2019

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

Полный код:

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

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

int c;

int output = 0;
FILE *infile;

while((c = getopt(argc, argv, "o:")) != -1){
    switch(c){

        case 'o':
            if(output){

                exit(EXIT_FAILURE);
            }
            output = 1;

            break;
        case '?':
            exit(EXIT_FAILURE);
        default:
            exit(EXIT_FAILURE);
    }
}

    for(; optind< argc; optind++) {
    infile = fopen(argv[optind], "r");


    size_t cpos = 0;
    char str[100];

    int ch;
    while((ch = fgetc(infile)) != EOF ) {
        if(ch == '\n' || ch == ' '){
            fprintf(stderr, "%s\n", str);
            str[0] = '\0';
            continue;
        } else{
            str[cpos++] = ch;
        }

    } 

    str[cpos] = 0;
    fprintf(stderr, "%s\n", str);

    fclose(infile);

    }
    exit(EXIT_SUCCESS);
    }

Моя проблема является частью инструкции while:

    for(; optind< argc; optind++) {
    infile = fopen(argv[optind], "r");

    size_t cpos = 0;
    char str[100];

    int ch;
    while((ch = fgetc(infile)) != EOF ) {
        if(ch == '\n' || ch == ' '){
            fprintf(stderr, "%s\n", str);
            str[0] = '\0';
            continue;
        } else{
            str[cpos++] = ch;
        }
    } 

    str[cpos] = 0;
    fprintf(stderr, "%s\n", str);

    fclose(infile);

    }

В infile = fopen(argv[optind], "r") Я сохраняю имя файла из argv. В заявлении while я читаю символы с infile с fgetc до EOF. Я хочу читать каждый символ, пока не наберу пустую строку или пробел. Когда я нажимаю '\n' или ' ', я хочу отобразить это на stderr, сбросить эту строку на пустую и продолжить читать символы в следующей строке. В противном случае ch будет помещен в str[cpos] (cpos увеличивает каждый цикл). В конце str[cpos] устанавливается на 0, чтобы отметить конец строки, последний str печатается и закрывается.

Проблема:

если я введу .txt файл (./program -o out.txt input.txt)

word1
word2
word3

Все, что я получаю, это

word1

Я пытался установить str[0]= '\0' как пустую строку, но после этого ничего не сохраняется на str. Как вывести все 3 слова?

Ответы [ 3 ]

2 голосов
/ 08 апреля 2019

Я вижу несколько потенциальных проблем:

  1. Вы должны сбросить cpos на ноль при обнаружении пробела.
  2. Перед fprintf в цикле, вы должны быть уверены, чтоnul-terminate текущей строки.
  3. Если последний символ перед EOF равен \n или , в конце вы получите пустую строку.
  4. Я не знаю вашегонабор данных, но я все равно буду помнить о превышении 99 символов ввода, так как вы можете переполнить буфер при первом обнаружении слова из 100 или более символов.
1 голос
/ 08 апреля 2019

Когда вы знаете, что в вашем массиве str есть все символы из слова, вы должны добавить в свой массив терминатор (нулевой байт) и сбросить cpos в 0, прежде чем собирать символы для нового слова.

Итак, представьте, что str это {'w', 'o', 'r', 'd'} и cpos 4 ты делаешь str [cpos] = 0 и тогда str равен {'w', 'o', 'r', 'd', 0} и это правильная строка с нулевым символом в конце

Пустая строка: {0}, это правильно

В любом случае не забудьте сбросить cpos на 0, так как в противном случае вы будете писать после терминатора.

1 голос
/ 08 апреля 2019

Вы не завершили нулем строку, которую создали, и не сбросили cpos = 0; для следующего слова.

В результате вы продолжаете писать в str[] дальше,за пределами '\0', с которым вы его завершили.

Цикл должен быть таким:

while((ch = fgetc(infile)) != EOF ) {
    if(ch == '\n' || ch == ' '){
        str[cpos] = '\0';               // terminate this string
        fprintf(stderr, "%s\n", str);
        cpos = 0;                       // for next word
    } else{
        str[cpos++] = ch;
    }
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...