2017-02-13 6 views
0

Я пытаюсь создать функцию, которая получает строку текста, а затем инвертирует каждое слово и возвращает массив строк. Это мой код. Что-то явно не так. Любые предложения по моим ошибкам здесь?c функция инвертировать строку

char** function(char* str, int* pn) 
{ 
    char temp[21]; 
    int n_of_spaces = 0, i = 0, d = 0; 

    for (int i = 0; str[i]; i++) 
     if (str[i] == ' ') 
      n_of_spaces++; 

    *pn = n_of_spaces + 1;  //should be number of words 
    char** s = (char**)calloc(*pn, sizeof(char*)); 

    while (str[i]) 
    { 
     d = 0; 
     if (i != 0) 
      i++; 

     while (str[i] != ' ' && str[i] != 0) 
     { 
      i++; 
      d++; 
     } 
     for (int j = 0; j < d; j++) 
      temp[j] = str[i]; 

     for (int k = 0; k < *pn; k++) 
     { 
      s[k] = (char*)calloc(d + 1, sizeof(char)); 
      strcpy(s[k], temp); 
      invert(s[k]);  //inverts a word 
     } 
    } 
    return s; 
} 

// Heres главный

int main() 
{ 
    int n_of_words; 
    char line[100]; 
    gets(line); 
    char** s = function(line, &n_of_words); 

    for (int i = 0; i < n_of_words; i++) 
    { 
     puts(s[i]); 
     free(s[i]); 
    } 

    free(s); 
    return 0; 
} 
void invert(char* s) 
{ 
int t; 
for (int i = 0, j = strlen(s) - 1; i < j; i++, j--) 
{ 
    t = s[i]; 
    s[i] = s[j]; 
    s[j] = t; 
} 

}

+0

ошибка времени выполнения, он ничего не делает, видимо – smiljanic997

+0

Можете ли вы пройти через это с помощью отладчика? – chrisaycock

+0

это всего лишь одна функция кода, но я думаю, что логика за ней неверна – smiljanic997

ответ

1

Прежде всего не использовать gets, это может вызвать переполнение буфера, потому что вы точно не знаете, количество байт, которые будут читать , Вместо этого используйте fgets.

Во-вторых, не выдавайте результат malloc и calloc на ваш тип указателя. Это может привести к потере некоторых важных предупреждений.

Наверное, Юрий Ивашкевич сказал, что лучше использовать функцию strtok, чтобы разделить вашу строку.

После этого все переменные temp имеют статический размер 21, который может быть переполнен при копировании в него данных. И когда вы копируете данные, вы не устанавливаете символ завершения строки \0. Поэтому, когда вы вызываете strcpy, он не может найти конец строки, и вы получаете неопределенное поведение.

+0

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

+0

@ChrisTurner трудно заметить все. Посмотрите на обновление, пожалуйста, может быть, я что-то упустил. –

+0

Более того, вы упомянули одну из наиболее очевидных проблем в комментариях, о которых я думал. –

0

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

Обратите внимание на следующее:

1) прототип функции main изменилось.
2) прототип function() изменен.
3) использование strdup() вместо calloc(). (для упрощения)
4) вся работа выполнена в function(), то есть нет invert().

Это будет скомпилировано и запущено для изменения строки ввода до 99 символов.

char* function(char* str, int* pn) 
{ 
    if(!str) return ""; 
    char *newStr = strdup(str); 
    int len, i=0; 
    len = strlen(str); 
    while(str[i]) 
    { 
     newStr[len-1-i]=str[i]; 
     i++; 
    } 
    str[i]=0; 
    strcpy(str, newStr); 
    free(newStr); 

    *pn = i-1; 

    return str; 
} 

//heres main 

int main(void) 
{ 
    int n_of_words; 
    char line[100]; 
    char line2[100]; 
    gets(line); 

    strcpy(line2, function(line, &n_of_words)); 

    printf("reversed line: %s", line2); 

    return 0; 
} 

EDIT (для адреса комментария)
Предлагаемый подход к лопнувшей струны вслова:
1) Используйте два шага для чтения, первым прочитал кол пробелов и длинный слово.
2) Используйте информацию на первом шаге, чтобы создать пространство для count строки, каждый самый длинный +1 long.Предлагайте, используя отдельные функции для создания/бесплатно этой памяти, например:

char ** Create2DStr(int numStrings, int maxStrLen) 
{ 
    int i; 
    char **a = {0}; 
    a = calloc(numStrings, sizeof(a)); 
    for(i=0;i<numStrings; i++) 
    { 
     a[i] = calloc(maxStrLen + 1, 1); 
    } 
    return a; 
} 

void free2DStr(char ** a, int numStrings) 
{ 
    int i; 
    for(i=0;i<numStrings; i++) 
    { 
     if(a[i]) free(a[i]); 
    } 
    free(a); 
} 

3) Второе чтение через исходную строку, чтобы разбить его на «слова» и поместите каждое «слово» в строки, которые вы создали. Сделайте это в петле count +1 раз. Существует много подходов, которые будут работать: strtok(...) для синтаксического анализа пробелов или побайтового символьного назначения в каждую строку, каждый раз индексируя цикл byte==space.
4) В следующем цикле обработайте каждую новую строку с помощью function() выше, чтобы отменить порядок символов.

+0

, не уверен, как это должно быть полезно, поскольку оно не адресуется вопросы в вопросе –

+0

@ChrisTurner - Title - функция _c для инвертирования строки_. Это иллюстрирует упрощенный подход и предлагается в качестве альтернативы некоторым из тех проблем, которые вы упомянули в других комментариях. – ryyker

Смежные вопросы