Ich versuche zu üben, indem ich ein kleines, kurzes Programm schreibe, um eine Textdatei einzulesen und ihren Inhalt in ein Array zu legen. Ich wollte dieses Programm schreiben, um jede Textdatei als String einzulesen und in einem Array zu speichern. Auf diese Weise können Sie jede Datei lesen und unabhängig von der Länge der Zeichenfolge ein Array dynamisch erstellen und es mit einer Datei füllen. Ich benutze dies als eine Übung, um mit C zu üben und hoffe, dies auf andere Typen und Strukturen zu extrapolieren.C scanf string array
Aus irgendeinem Grund stimmt mein erster Eintrag nicht überein, was zu unerwartetem Verhalten führt, aber zumindest keine Seg-Fehler. Ich verstehe, dass mit C, müssen Sie im Wesentlichen Mikro alle Ihre Speicher verwalten, und arbeiten mit dem Code, ich habe versucht, Speicher für jeden Eintrag zu reservieren, aber ist dies der richtige Ansatz? Ich habe den Code durch meinen Kopf laufen lassen, und es macht logisch Sinn, wenn ich mit 0 Einträgen anfange, aber ich verstehe nicht, warum der erste Eintrag fehlschlägt, während die restlichen Einträge funktionieren.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
//Initialize variables and pointers
//Create an array of chars to use when reading in
//Create an array of strings to store
//i : use to keep track of the number of strings in array
//j : loop variable
//size: size of string
char *s = (char *) malloc(sizeof(char));
int i=0,j=0;
int size = 0;
char **a = (char **) malloc(sizeof(char *));
//Read in string, assign string to an address at a[]
while(scanf("%79s",s) == 1){
//Get the size of the input string
size = (unsigned) strlen(s);
//Print some notes here
printf("\nString is \"%-14s\"\tSize is %-3d, i is currently %d\n",s,size,i);
printf("Using MALLOC with %d bytes\n",size+1);
//Allocate memory to copy string
//
//For some reason, the commented code works
//a[i] = (char *) (malloc(sizeof(char)*(size+1)) + 'a');
a[i] = (char *) (malloc(sizeof(char)*(size+1)));
//Go and allocate memory for each character in string to store
for(j=0; j<(size+1); j++) a[i][j] = (char) (malloc(sizeof(char)));
//Print some more notes here
printf("Size: a[%2d] is %3d bytes, *a[%2d] is %3d bytes, Length of a[%2d] is %d\n",i,(int) sizeof(a[i]),i,(int) sizeof(*a[i]),i,(unsigned) strlen(a[i]));
//Copy over string and set last char to be end
for(j=0; j<size; j++) a[i][j] = (char) s[j];
a[i][size] = '\0';
//Print it out and increase i
printf("a[%3d] is now %s\n",i,a[i]);
i++;
}
printf("I is now %d\n\n\n",i);
a[i] = NULL;
//print out array
for(j=0; j<i; j++) printf("%3d. %-40s\n",j,a[j]);
return 0;
}
Test-Textdatei (numbers.txt):
1
22
333
4444
55555
666666
7777777
88888888
9999999
0000000000
11111111111
222222222
Befehl:
./a.out < numbers.txt
Ergebnisse:
String is "1 " Size is 1 , i is currently 0
Using MALLOC with 2 bytes
Size: a[ 0] is 8 bytes, *a[ 0] is 1 bytes, Length of a[ 0] is 2
a[ 0] is now 1
String is "22 " Size is 2 , i is currently 1
Using MALLOC with 3 bytes
Size: a[ 1] is 8 bytes, *a[ 1] is 1 bytes, Length of a[ 1] is 3
a[ 1] is now 22
String is "333 " Size is 3 , i is currently 2
Using MALLOC with 4 bytes
Size: a[ 2] is 8 bytes, *a[ 2] is 1 bytes, Length of a[ 2] is 4
a[ 2] is now 333
String is "4444 " Size is 4 , i is currently 3
Using MALLOC with 5 bytes
Size: a[ 3] is 8 bytes, *a[ 3] is 1 bytes, Length of a[ 3] is 5
a[ 3] is now 4444
String is "55555 " Size is 5 , i is currently 4
Using MALLOC with 6 bytes
Size: a[ 4] is 8 bytes, *a[ 4] is 1 bytes, Length of a[ 4] is 6
a[ 4] is now 55555
String is "666666 " Size is 6 , i is currently 5
Using MALLOC with 7 bytes
Size: a[ 5] is 8 bytes, *a[ 5] is 1 bytes, Length of a[ 5] is 7
a[ 5] is now 666666
String is "7777777 " Size is 7 , i is currently 6
Using MALLOC with 8 bytes
Size: a[ 6] is 8 bytes, *a[ 6] is 1 bytes, Length of a[ 6] is 8
a[ 6] is now 7777777
String is "88888888 " Size is 8 , i is currently 7
Using MALLOC with 9 bytes
Size: a[ 7] is 8 bytes, *a[ 7] is 1 bytes, Length of a[ 7] is 9
a[ 7] is now 88888888
String is "9999999 " Size is 7 , i is currently 8
Using MALLOC with 8 bytes
Size: a[ 8] is 8 bytes, *a[ 8] is 1 bytes, Length of a[ 8] is 8
a[ 8] is now 9999999
String is "0000000000 " Size is 10 , i is currently 9
Using MALLOC with 11 bytes
Size: a[ 9] is 8 bytes, *a[ 9] is 1 bytes, Length of a[ 9] is 11
a[ 9] is now 0000000000
String is "11111111111 " Size is 11 , i is currently 10
Using MALLOC with 12 bytes
Size: a[10] is 8 bytes, *a[10] is 1 bytes, Length of a[10] is 12
a[ 10] is now 11111111111
String is "222222222 " Size is 9 , i is currently 11
Using MALLOC with 10 bytes
Size: a[11] is 8 bytes, *a[11] is 1 bytes, Length of a[11] is 10
a[ 11] is now 222222222
I is now 12
0. ▒"▒
1. 22
2. 333
3. 4444
4. 55555
5. 666666
6. 7777777
7. 88888888
8. 9999999
9. 0000000000
10. 11111111111
11. 222222222
Nicht definiertes Verhalten für die Verwendung des Werts eines Objekts mit automatischer Speicherdauer, während es nicht initialisiert ist. Undefiniertes Verhalten zum Übergeben eines falschen Argumenttyps an eine varargs-Funktion. Undefiniertes Verhalten für 'fflush()' 'einen nicht ausgegebenen Stream. – EOF
Sie müssen mehr tun, als einen Zeiger zu deklarieren ... Sie müssen auch Speicher für die gelesenen Strings zuweisen (und das Array von Zeigern darauf). Möglicherweise müssen Sie die Größe dieser Zuordnungen auch ändern, wenn Sie nicht wissen, wie viel Speicherplatz Sie benötigen. – Dmitri
Wenn Sie 'scanf' mit Strings verwenden, brauchen Sie nicht das' & '. Jedes Element in Ihrem Array 'a' ist eine Zeichenkette,' a [0] 'ist die erste' a [1] 'die zweite, usw. Wenn Sie eine Zeichenkette ausgeben, verwenden Sie einfach den _name_ des string/char-Arrays (Der Zeiger auf das erste Element im char-Array. Um also einen String ('char *') auszugeben, der ein Element im Array 'a' ist, würde man einfach 'printf' (meine erste Zeile ist:% s \ n ", a [0]);'. Außerdem würden Sie niemals '&' zum Ausdruck einer Zeichenkette (oder eines pointer-to-struct int, zB) verwenden, Sie würden stattdessen den Operator '*' benutzen, wenn nötig (aber wiederum nicht mit Strings, weil _pects_ der ptr selbst). – RastaJedi