2014-02-03 5 views
0

Если я поместил «&» в printf, он по крайней мере напечатает имена стран, и он потерпит крах. В противном случае он немедленно сработает. Я предполагаю, что что-то не так с циклом for. Дай мне знать, если я ошибаюсь.Почему я не могу отображать строки со следующим кодом?

//Implementation file// 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
struct list 
{ 
    char *item; 
    int length; 
}; 
typedef struct list LIST; //aliasing the structure// 
LIST *create()  //constrcutor// 
{ 
    LIST *L = (LIST*)malloc(sizeof (LIST)); 
    L->length=0; 
    return L; 
} 
void insert(LIST* L, char *newitem) 
{ 
    L->item=(char*)malloc(sizeof(char)); 
    strcpy(L->item, newitem); 
    (L->length)++; 
} 
void display(LIST *L) 
{ 
    int i; 
    for(i=0;i<(L->length);i++) 
    { 
     printf("Elements are: %s\n", L->item[i]); 

    } 
} 
int main() 
{ 
    LIST *L; 
    L=create(); 
    insert(L, "America"); 
    insert(L, "Brazil"); 
    display(L); 
    free(L->item); 
    free(L); 
    return 0; 
} 
+3

Ваш код списка полностью сломан. В 'insert' вы выделяете пространство только для одного символа, когда вы должны выделять достаточно для длины' newitem'. Кроме того, при каждом вызове 'insert' вы перезаписываете головку списка (потерять предыдущие элементы) вместо фактического добавления. В 'display' вы пытаетесь напечатать каждый элемент путем индексирования массива в строку в элементе head, что просто не имеет смысла. –

ответ

3

Там же гигантская ошибка в коде: при вставке новых элементов вы должны создать новый элемент списка и инициализировать его ..

с помощью функции

void insert(LIST* L, char *newitem) 
{ 
    L->item=(char*)malloc(sizeof(char)); 
    strcpy(L->item, newitem); 
    (L->length)++; 
} 

называется так:

insert(L, "America"); 
insert(L, "Brazil"); 

вы всегда писать один и тот же элемент для длины и распределение новой памяти (даже без использования/хранения указателя на старый выделяемой один .. который потерял!).

Вы должны скорее сделать что-то вроде:

//Implementation file// 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
struct list 
{ 
    char *item; 
    struct list* next; 
}; 
typedef struct list LIST; //aliasing the structure// 
LIST *create()  //constrcutor// 
{ 
    LIST *L = (LIST*)malloc(sizeof (LIST)); 
    L->next = 0; 
    return L; 
} 
LIST* insert(LIST* L, char *newitem) 
{ 
    L->item=(char*)malloc(sizeof(char)*strlen(newitem)); 
    strcpy(L->item, newitem); 
    LIST *newL = (LIST*)malloc(sizeof (LIST)); 
    newL->next = 0; 
    L->next = newL; 
    return newL; 
} 
void display(LIST *L) 
{ 
    int i; 
    for(i=0; L->next != 0;L = L->next) // Assumes there's at least 1 item 
    { 
     printf("Elements are: %s\n", L->item); 
    } 
} 
int main() 
{ 
    LIST *startElement; 
    startElement=create(); 
    LIST *lastElement = insert(startElement, "America"); 
    lastElement = insert(lastElement, "Brazil"); 
    display(startElement); 
    // Free all memory.. exercise :) 
    return 0; 
} 

Попробуйте интерактивно: http://ideone.com/n8tRtv

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

Обратите внимание, что приведенный выше код

  1. не освобождает память

  2. Всегда предполагает, что существует, по крайней мере элемент в списке

Если вы хотите полный код, хорошо .. исправить. Если вы понимаете, как это работает, должно быть вполне возможно исправить это полностью. Удачи!

+0

Ничто в OP не подразумевает связанный список. – gmorrow

+0

Помимо имени «списка», подполе «item» и функции «insertElement» вы имеете в виду? –

+0

А что подразумевает ссылки? – gmorrow

0

Указатель неверно в спецификации printf. Вы используете %s который ожидает char*, но вы проходите мимо char. В результате printf реализации обрабатывает значение символа в качестве адреса и быстро убегала в недействительную память и грохот

Чтобы это исправить, нужно переключиться на использование %c

printf("Elements are: %c\n", L->item[i]); 

Обратите внимания, что это вызовет каждое char распечатать на другой строке. Скорее всего, вы хотите что-то вроде следующего

printf("Elements are: %s\n", L->item[i]); 
int i; 
for(i=0;i<(L->length);i++) 
{ 
    printf("%c", L->item[i]); 

} 
printf("\n"); 

Обратите внимание, что если ваша цель состоит, чтобы быть item члена оканчивающегося нуля char* то самое простое исправление сделать следующий

printf("Elements are: %s\n", L->item); 
+0

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

+0

@anansharm для печати символа 'char *' вам нужно значение null char с символом null. Учитывая, что у вас есть длина, связанная с символом 'char *', я предполагал, что он не был завершен нулем, поэтому я решил распечатать отдельные символы – JaredPar

+3

-1, гораздо проще было бы сделать 'printf ("% s ", L-> item); ' –

3
L->item=(char*)malloc(sizeof(char)); 
strcpy(L->item, newitem); 

Вы выделяете только один байт, но вы пытаетесь скопировать целую строку в L->item, что приводит к неопределенному поведению. Это должно быть:

L->item=malloc(sizeof(char)*(strlen(newitem)+1)); 
strcpy(L->item, newitem); 

Вы также вызвать функцию insert дважды, которая будет выделять новую память для L->item и снимите указатель на предыдущее выделенное пространство -> утечку памяти. Вы должны добавлять элементы списка вместо того, чтобы перезаписывать первое все время, см. Ответ @ DavidKernin.

0
L->item=(char*)malloc(sizeof(char)); 

одна проблема в коде

+2

И, может быть, вы объясните OP, что там не так и как это исправить? –

+0

@ Roma-MT - вы можете взять лошадь на воду, но вы не можете ее выпить –

1

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

struct list 
{ 
    char **item; 
    int length; 
}; 

struct list теперь содержит массив указателей на char *.

LIST *create() 
{ 
    LIST *L = (LIST*)malloc(sizeof (LIST)); 
    L->item = (char **)malloc(sizeof(char *)); 
    L->length=0; 
    return L; 
} 

Это будет подходящий способ для malloc для вашего списка.

void insert(LIST* L, char *newitem) 
{ 
    L->item[L->length] = (char *)malloc(sizeof(char *));  
    strcpy(L->item[L->length++], newitem); 
} 

Чтобы вставить вам таНос для нового указателя полукокса, который находится в конце вашего массива символьных указателей. Вставленная строка копируется и длина увеличивается.

И не забудьте бесплатно()!

+0

С вашим кодом я смог получить результаты, которые я хотел. Я очень новичок в структуре данных, поэтому не уверен, неправильно ли сформулировал вопрос. Тем не менее, я хотел, чтобы иметь возможность манипулировать данными, например сортировать имя страны и удалять название страны и тому подобное. Я могу делать все манипуляции в регулярном массиве. Я не знаю, почему я не могу это сделать в строках. Во всяком случае, спасибо за усилия. – anansharm

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