2015-12-18 2 views
0

Таким образом, в настоящее время эта функция может принимать только 9 слов по 10 символов. Как сделать так, чтобы он мог взять arbitrary сумму words и characters и выполнить их сортировку по алфавитным номерам?Как заставить эту функцию принимать произвольные строки?

int sortText(){ 
    char name[10][9], tname[10][9], temp[10]; 
    int i, j, n; 

    printf("Enter the amount of words you want to sort (max 9):"); 
    scanf("%d", &n); 
    printf("Enter %d words: ",n); 
    for (i = 0; i < n; i++) 
    { 
     scanf("%s", name[i]); 
     strcpy(tname[i], name[i]); 
    } 
    for (i = 0; i < n - 1 ; i++){ 
     for (j = i + 1; j < n; j++){ 
      if (strcmp(name[i], name[j]) > 0){ 
       strcpy(temp, name[i]); 
       strcpy(name[i], name[j]); 
       strcpy(name[j], temp); 
      } 
     } 
    } 
    printf("\n------------------------------------------\n"); 
    printf("%-3s %4s %11s\n", "Input","|", "Output"); 
    printf("------------------------------------------\n"); 
    for (i = 0; i < n; i++) 
    { 
     printf("%s\t\t%s\n", tname[i], name[i]); 
    } 
    printf("------------------------------------------\n"); 
    } 
+3

Нет, это может занять 10 слов с 8 символов каждый (плюс строка терминатор). –

+1

Вам нужно будет сохранить строки в качестве указателей на символы в динамически распределенном массиве. Затем вы можете отсортировать элементы 'char *' в массиве. Таким образом, строки и массив могут иметь любую длину. – Baldrick

+0

благодарит за отзыв, как бы вы предложили мне это сделать? Я только программировал C со статическими значениями до, а не произвольной длины. – Joel

ответ

0

Только для C вы должны использовать указатель символов, расположенный динамически. Вы можете составить список путем реализации связанного списка. Тогда strcmp все еще работает хорошо. См о связанном списке здесь: http://www.cprogramming.com/tutorial/c/lesson15.html

3

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

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

Если мы начнем с типов данных и как вы должны хранить свои строки, то вы хотите, чтобы массив массивов, как и сейчас, но динамически распределялся, что означает, что вам нужен массив указателей (к строки), но поскольку массив строки также должен быть динамическим, вам нужен указатель на массив, содержащий указатели на другие массивы, то есть указатель на указатель на char: char **.

Теперь, когда мы знаем, какой тип данных использовать, подумайте о том, как его выделить. Для того, чтобы выделить место для одной строки в массиве, вы выделяете один char * с помощью функции malloc:

char **strings = malloc(1 * sizeof(char *)); 

Это была простая часть. Теперь, прежде чем мы начнем чтение фактической строки, позволяет думать о том, как добавить новую строку в коллекцию: Это делается перераспределение массива строк, которые вы имеете, используя realloc функцию:

char **temp_strings = realloc(strings, current_count + 1 * sizeof(char *)); 
if (temp_string == NULL) 
{ 
    // Allocation failed, handle error appropriately 
} 
strings = temp_strings; 
++current_count; 

Здесь переменная current_count - это текущая длина массива строк, она должна быть первоначально инициализирована до 1 (так как у нас только одна строка в массиве).

Теперь для чтения фактических строк, и это немного сложнее, поскольку мы на самом деле не можем читать целые строки (так как мы не знаем, как долго каждая строка). Вместо этого мы читаем по одному персонажу за раз и заканчиваем, когда попадаем в новую строку. Нам также нужно перераспределить строку для каждого символа.

Может быть что-то вроде этого:

int ch; 
char *s = NULL; 
size_t current_length = 0; // Current length of string 

while ((c = fgetc(stdin)) != EOF) 
{ 
    if (c == '\n') 
     break; // Newline, done with the current string 

    if (s == NULL) 
    { 
     s = malloc(2); // Allocate two character: One for c and one for the terminator 
    } 
    else 
    { 
     // The current length is not including the terminator 
     // that's why we add two characters 
     char *temp_s = realloc(s, current_length + 2); 
     if (temp_s == NULL) 
     { 
      // Handle error 
     } 
     s = temp_s; 
    } 

    s[current_length++] = c; 
    s[current_length] = '\0'; // Terminate as a string 
} 

if (s != NULL) 
{ 
    // "Add" the string to the array of strings 
    strings[current_count] = s; 
} 
+0

Большое вам спасибо за отзыв. однако, когда я пытаюсь реализовать ваш код, он генерирует много ошибок. Märkte att du var svensk när jag gick in på din profil.Как бы вы посоветовали мне включить наши решения в единое целое? :) mvh joel. – Joel

+0

@Joel Quiet на работу (тихо, на работе), так что я сделал полную программу для вас, чтобы читать и тест: http://ideone.com/s7yWQ8 –

+0

большое спасибо за ваше время Joachim вы положили в помощь мне. К сожалению, это не совсем то, что я ищу. Если вы попытаетесь запустить исходную программу, вы увидите, что она сортируется по алфавиту, а не по длине. Некоторые вопросы: почему вы используете FILE *? Вся информация должна быть прочитана через fgets/getline :). Может быть, это было неясно, но то, что я ищу, - это не другая программа, а только то, как я получаю свою программу для получения случайных длинных строк и много-много строк :) Надеюсь, у вас хорошая пятница! – Joel

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