Поменяйте слова в предложении в "C" - PullRequest
1 голос
/ 03 апреля 2019

У меня есть задание из школы, в котором я должен создать проект, который принимает аргументы из CMD, каждый аргумент состоит из двух слов, разделенных /, затем мы вставляем предложение, и программа должна найти все вхожденияпервого слова и замени его вторым, я просто пытаюсь заставить его работать, используя strtok_r.

Вот мой код:

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

int main(int args, char *argv[]) {
    char *token;
    char *token2;
    char veta[1000];
    int i, j, k;
    int err;
    char *saveptr1, *saveptr2;

    if (fgets(veta, 1000, stdin)) {
        token = strtok_r(veta, " \n", &saveptr1);
        k = 1;
        while (token != NULL) {
            printf("Cycle %d: \n", k++);
            printf("%s\n", token);
            for (i = 1; i < args; i++) {
                token2 = strtok_r(argv[i], "/", &saveptr2);
                printf("%s ", token2);
                token2 = strtok_r(NULL, "/", &saveptr2);    
                printf("%s \n", token2);
            }   
            token = strtok_r(NULL, " \n", &saveptr1);
        }   
    }
    return(0);
}

, когда я набираю аргументы в CMD и вставляю предложение, например, с четырьмя словами, выполняется 4 цикла, но вывод не такой, как я хочубыть ... Например, когда я даю следующие аргументы: hi/hello how/good no/yet и вставляю предложение, получается:

Cycle1: 
(first word of sentence)
hi hello
how good
no yet
Cycle4: 
(second word of sentence)
hi (null)
how (null)
no (null)
Cycle4: 
(third word of sentence)
hi (null)
how (null)
no (null)
Cycle4: 
(fourth word of sentence)
hi (null)
how (null)
no (null)

, когда это должно быть так:

Cycle1: 
(first word of sentence)
hi hello
how good
no yet
Cycle4: 
(second word of sentence)
hi hello
how good
no yet
Cycle4: 
(third word of sentence)
hi hello
how good
no yet
Cycle4: 
(fourth word of sentence)
hi hello
how good
no yet

Я не могу бытьв состоянии это исправить, вы можете мне помочь?

Заранее спасибо.

1 Ответ

0 голосов
/ 03 апреля 2019

Как я уже сказал, замечание strtok_r измените свой первый аргумент, вам нужно сначала сохранить слова из argv

Я также призываю вас не изменять argv и проверять правильность аргументов, проверяя результат strtok или strtok_r


Вы можете сделать, например:

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

int main(int argc, char *argv[])
{
  char ** first = malloc((argc - 1) * sizeof(char *));
  char ** second = malloc((argc - 1) * sizeof(char *));
  int i;

  for (i = 1; i != argc; ++i) {
    char * s = strdup(argv[i]);

    if (((first[i - 1] = strtok(s, "/")) == NULL) ||
        ((second[i - 1] = strtok(NULL, "/")) == NULL)) {
      fprintf(stderr, "invalid argument '%s'\n", argv[i]);
      return -1;
    }
    /* debug */
    else
      printf("first[%d]='%s' second[%d]='%s'\n", i-1, first[i-1], i-1, second[i-1]);

  }

  /*
  here you read sentences and do the substitutions
  */

  /* free resources */
  for (i = 0; i != argc - 1; ++i) {
    free(first[i]);
  }
  free(first);
  free(second);

  return(0);
}

Компиляция и исполнение:

/tmp % gcc -g -pedantic -Wall -Wextra c.c
/tmp % ./a.out hi/hello how/good no/yet
first[0]='hi' second[0]='hello'
first[1]='how' second[1]='good'
first[2]='no' second[2]='yet'

Исполнение под valgrind :

/tmp % valgrind ./a.out hi/hello how/good no/yet
==29457== Memcheck, a memory error detector
==29457== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==29457== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==29457== Command: ./a.out hi/hello how/good no/yet
==29457== 
first[0]='hi' second[0]='hello'
first[1]='how' second[1]='good'
first[2]='no' second[2]='yet'
==29457== 
==29457== HEAP SUMMARY:
==29457==     in use at exit: 0 bytes in 0 blocks
==29457==   total heap usage: 5 allocs, 5 frees, 73 bytes allocated
==29457== 
==29457== All heap blocks were freed -- no leaks are possible
==29457== 
==29457== For counts of detected and suppressed errors, rerun with: -v
==29457== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

Обратите внимание, что можно сделать

  char * first[argc - 1];
  char * second[argc - 1];

скорее, чтобы выделить first и second в куче, но во время компиляции массивы имеют неизвестный размер в стеке, и я призываю вас не использовать этот способ

...