Forum: PC-Programmierung [C] String abfragen


von Elvir È. (elvir)


Lesenswert?

Hallo,

Wir müssen in der Schule ein Programm schreiben, welches von einer .txt 
Datei von Namen einen abfragen soll und ausgeben soll ob der Name in der 
Liste ist oder nicht.

Ich habe leider gar keine Ahnung wie ich das anstellen soll, bin quasi 
ein Anfänger im Gebiet C.

Ich hoffe ihr könnt mir weiterhelfen.

LG

von Udo S. (urschmitt)


Lesenswert?

Wenn ihr die Aufgabe bekommen habt, dann habt ihr auch die notwendigen 
Grundlagen dazu durchgenommen.
Du suchst jetzt einen dummen, der das Programm für dich schreibt, daß du 
in der Zeit abhängen, saufen oder mit dem Handy spielen kannst?

Wenn du konkrete Probleme hast wird dir hier gerne geholfen aber wenn du 
meinst wir sind blöd genug deine Hausaufgabe zu machen täuschst du dich.

Also leg vor, was hast du dir einfallen lassen und was funktioniert da 
nicht?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Elvir Ègalo schrieb:
> Hallo,
>
> Wir müssen in der Schule ein Programm schreiben, welches von einer .txt
> Datei von Namen einen abfragen soll und ausgeben soll ob der Name in der
> Liste ist oder nicht.
>
> Ich habe leider gar keine Ahnung wie ich das anstellen soll, bin quasi
> ein Anfänger im Gebiet C.

Ein Anfänger in C bekommt nicht die Aufgabe eine Textdatei auszulesen 
und jede eingelesene Zeile mit einem anderen String zu vergleichen.

(Und das ist dann auch schon der einzige Tip für das prinzipielle 
Vorgehen, den du hier erwarten kannst. Denn die beiden Bestandteile im 
oben genannten Vorgehen sind Basistechniken, die jeder C Programmierer 
können muss. Ein Anfänger noch nicht, aber einem Anfänger stellt man 
auch nicht eine derartige Aufgabe).

: Bearbeitet durch User
von Elvir È. (elvir)


Lesenswert?

Vielen Dank erstmal für die hilfreichen Kommentare

Das Problem ist, dass ich in genau diesem Fach, in dem wir C 
programmieren sitzen geblieben bin und unser Lehrer generell wenig 
erklärt und von uns erwartet, dass wir den Stoff uns selber aneignen. 
Und wenn wir Fragen stellen, die in seinen Augen dumm sind, hat er einen 
negativen Eindruck von uns.

Das hier habe ich schon:
1
#include <stdio.h>
2
#include <string.h>
3
#include <stdlib.h>
4
5
int main(void)
6
{
7
    char content[255];
8
    char name;
9
    
10
    FILE *fp;
11
    
12
    fp = fopen("Liste.txt","r");
13
    
14
    if (fp == NULL)
15
    {
16
        printf("Datei konnte nicht geöffnet werden\n");
17
    }
18
    
19
    else
20
    {
21
        printf("Datei wurde korrekt gelesen\n");
22
    }
23
    
24
    fputs(content, stdout);
25
    
26
    printf("Geben Sie den zu suchenden Namen ein\n");
27
    scanf("%c", &name);
28
    
29
    fgets(&name, 255, stdin);
30
    
31
    if (name == content)
32
    {
33
        printf("Der Name existiert in der Liste");
34
    }
35
36
    else
37
    {
38
        printf("Der Name existiert nicht in der Liste");
39
    }
40
    
41
    fclose(fp);
42
    
43
    return 0;
44
}

Natürlich kann es nicht funktionieren da ich jede einzelne Zeile 
vergleichen muss aber das wäre mein erster Vorschlag.

LG

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Elvir Ègalo schrieb:

>     char name;

So, so.
Du speicherst also einen Namen, der ja wohl aus mehr als 1 Zeichen 
besteht, in einer Variablen vom Typ char, die also genau 1 Zeichen 
aufnehmen kann.
Interessant. Da fehlet es an deinem Wissen mehr, als ich ürsprünglich 
dachte.


> Natürlich kann es nicht funktionieren da ich jede einzelne Zeile
> vergleichen muss aber das wäre mein erster Vorschlag.

Deine Probleme fangen schon früher an. Viel früher.

Zwischen String-Behandlung und Datei-Behandlung liegen in den meisten 
Lehrbüchern gut und gerne 60 bis 70 Seiten. Was hast du in der 
Zwischenzeit gemacht?

> Das Problem ist, dass ich in genau diesem Fach, in dem wir
> C programmieren sitzen geblieben bin

Traurig genug, dass du nach 2 Anläufen dann immer noch nicht gelernt 
hast, wie String-Verarbeitung in C tatsächlich funktioniert. Das ist 
zwar die erste gröbere Hürde für C-Programmierer, aber so schwer ist es 
auch wieder nicht.
Von dort (sicheres Beherrschen der String-Behandlung), bis zur 
File-Behandlung ist dann noch ein weiterer Weg. Aber solange 
String-Behandlung nicht sitzt, hat File-Behandlung mit Strings 
eigentlich keinen Sinn.

: Bearbeitet durch User
von cc (Gast)


Lesenswert?

Ich möchte von den C Profis zerfleischt werden... :P
1
#include <limits.h>
2
#include <stdio.h>
3
#include <stdlib.h>
4
5
int main (int argc, char* argv[]) {
6
  int i = 0, j = 0, k = 0;
7
  char *file = malloc (INT_MAX);
8
  gets (file);
9
10
  do {
11
    if (file[i] == argv[1][j]) {
12
      if (argv[1][j] == '\0') {
13
        puts ("enthalten");
14
        return 0;
15
      }
16
      k = !0;
17
      ++j;
18
    }
19
    else {
20
      if (file[i] == ' ' && k != 0) {
21
        puts ("enthalten");
22
        return 0;
23
      }
24
      j = k = 0;
25
    }
26
  } while (file[i++] != '\0');
27
28
  puts("nicht enthalten");
29
30
  return 0;
31
}

Von der Linux Konsole mit "a.out name < names.txt" aufgerufen, 
vorrausgesetzt die Datei names.txt ist einzeilig, findet das Programm 
Herraus, ob sein erster Parameter in der Datei steht.

von Bülent C. (mirki)


Lesenswert?

Elvir Ègalo schrieb:
> Natürlich kann es nicht funktionieren da ich jede einzelne Zeile
> vergleichen muss aber das wäre mein erster Vorschlag.

getline()

von Karl H. (kbuchegg)


Lesenswert?

cc schrieb:
> Ich möchte von den C Profis zerfleischt werden... :P

:-)

gets ist 'böse'.
Wobei ich jetzt auch unsicher bin, in wie fern das bei einem
  char *file = malloc (INT_MAX);
noch relevant ist.

> vorrausgesetzt die Datei names.txt ist einzeilig

hmm.
liese sich diese Einschränkung mit einem
1
      if (isspace(file[i]) && k != 0) {
aufheben. Ich denke 'ja', habs aber nicht probiert.

: Bearbeitet durch User
von cc (Gast)


Lesenswert?

>> vorrausgesetzt die Datei names.txt ist einzeilig
>
> hmm.
> liese sich diese Einschränkung mit einem
>
1
>       if (isspace(file[i]) && k != 0) {
2
>
> aufheben. Ich denke 'ja', habs aber nicht probiert.

Das Problem ist eigentlich, dass newline beim einlesen der Datei mit 
gets().

von Karl H. (kbuchegg)


Lesenswert?

cc schrieb:
>>> vorrausgesetzt die Datei names.txt ist einzeilig
>>
>> hmm.
>> liese sich diese Einschränkung mit einem
>>
1
>>       if (isspace(file[i]) && k != 0) {
2
>>
>> aufheben. Ich denke 'ja', habs aber nicht probiert.
>
> Das Problem ist eigentlich, dass newline beim einlesen der Datei mit
> gets().

Ja, natürlich. Daran hab ich jetzt nicht gedacht. War so damit 
beschäftigt, den Vergleichs-Sucher zu studieren, dass ich das glatt 
übersehen habe.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Von dort (sicheres Beherrschen der String-Behandlung), bis zur
> File-Behandlung ist dann noch ein weiterer Weg. Aber solange
> Strings-Behandlung nicht sitzt, hat File-Behandlung mit Strings
> eigentlich keinen Sinn.

In dem 'Programm' ist auch noch ein noch grundlegenderer Fehler 
enthalten, der dir zu dieser Zeit überhaupt nicht mehr passieren dürfte. 
Selbst dann nicht, wenn du nicht wiederholt hättest.
1
int main(void)
2
{
3
    char content[255];
4
5
...
6
    
7
    fputs(content, stdout);
8
...
9
}

content hat keinen gesicherten Inhalt/Wert. Was da also auf stdout 
ausgegeben wird, ist völlig undefiniert.
2. Frage: wozu wird da eigentlich ausgegeben? Macht das logisch gesehen 
überhaupt irgendeinen Sinn an dieser Stelle? Ich meine: nicht wirklich. 
Du hast es halt mal hingeschrieben, damit was dort steht.

: Bearbeitet durch User
von Vic (Gast)


Lesenswert?

Ich denke Elvir Ègalo wird wo anders betteln gehen......

von Karl H. (kbuchegg)


Lesenswert?

Vic schrieb:
> Ich denke Elvir Ègalo wird wo anders betteln gehen......

Es wird ihm nicht viel helfen.
Vielleicht findet er jemanden, der ihm das Pgm schreibt, zumal es ja 
auch nicht besonders umfangreich und/oder schwierig ist. Ich würde sogar 
soweit gehen, dass ein derartiges Programm in vielen Lehrbüchern mehr 
oder weniger im Kapitel "Filebehandlung" irgendwo vorkommt.
Nur hilft ihm das nicht viel. Für einen halbwegs aufmerksamen Lehrer ist 
es ein leichtes festzustellen, ob er das selbst geschrieben hat oder 
nicht. Ein paar Fragen zum Code genügen. Eine kleine Zusatzaufgabe, die 
er live erledigen muss und es ist offensichtlich, dass das abgegebene 
funktionierende Programm nicht von ihm stammen kann.
Niemand katapultiert sich von heute auf morgen vom gezeigten Level auf 
ein akzeptabel gutes Niveau. Dazu fehlt es im geposteten zu weit. Da 
sind nicht einfach nur ein oder zwei kleinere Probleme vorhanden, da 
liegt viel zu viel im Argen, was nicht sein dürfte.
Willst du mir weiß machen, du wärst in einer Tour de France Etappe fast 
Vorletzter geworden, kannst aber noch nicht mal mit Stützrädern ohne 
umkippen Rad fahren, dann ist recht offensichtlich, dass du geflunkert 
hast.

: Bearbeitet durch User
von Bülent C. (mirki)


Lesenswert?

Das Internet wimmelt nur von Lösungsansätzen....
Hier z.B.
http://openbook.galileocomputing.de/c_von_a_bis_z/016_c_ein_ausgabe_funktionen_001.htm##mj136f9ac6b5b7c440aafe5010411ef011

Das Dilemma ist ja, das viele garnicht verstehen, das Problem 
vollumfänglich erkennen zu müssen, bevor man sich an die Lösung 
ranmacht.

von Vic (Gast)


Lesenswert?

<offtopic>
kennt jemand den Film "Idiocracy"
</offtopic>

von cccccc (Gast)


Lesenswert?

Elvir Ègalo schrieb:
> Wir müssen in der Schule ein Programm schreiben, welches von einer .txt
> Datei von Namen einen abfragen soll und ausgeben soll ob der Name in der
> Liste ist oder nicht.

1. Datei öffnen
2. Inhalt in den Speicher laden
3. Zeichen für Zeichen durch den Speicher durchgehen, und mit dem 
Suchnamen vergleichen.
3a. Schleife über den Dateiinhalt der Länge N
3b. Schleife über Suchname und zeichenweise mit Dateiinhalt vergleichen
4. Wenn Übereinstimmung gefunden, dann ist es in der Liste
5. Wenn Schleife durchlaufen, ohne etwas zu finden, dann ist es eben 
nicht in der Liste


Das einzig schwierige ist der Punkt 3.
Pseudocode ohne jegliche Optimierung, auch sind gewisse Fehler nicht 
abgefangen:
1
bool found;
2
for(i from 0 to length(dateiinhalt)-length(suchname))
3
{
4
 found=true;
5
 for(j from 0 to length(suchname))
6
 {
7
  if(dateiinhalt[i+j]!=suchname[j])
8
   found=false;
9
 }
10
 if(found)
11
  puts("juhu gefunden!!!");
12
}
Noch was: Irgendwann ist die Schule vorbei, und dann kannst du dich 
nicht mehr auf die schlechten und bösen Lehrer ausreden.
Die Aufgabe hier ist vielleicht nicht ganz einfach für Anfänger, aber 
auch nicht unmöglich.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

cccccc schrieb:

> 2. Inhalt in den Speicher laden

Ich denke sein Lehrer wäre auch dann zufrieden, wenn er postuliert, dass 
pro Zeile ein Name steht und er eine Zeile mittels fgets (getline wäre 
natürlich noch besser, aber dann ist er schon bei 2-* Programmierung und 
die ist erfahrungsgemäss für Lernende nicht so einfach) einliest, mit 
dem Suchstring vergleicht und eventuelle Übereinstimmung feststellt.
Wenn das jemand so hinkriegt (was nicht weiter schwer ist), dann würde 
mir das als Lehrer reichen, denn darauf kann man weiteres aufbauen - 
"Recordmässiges" Lesen einer Datei, und sei es nur ein Record mit einem 
Member pro Record und Zeile, ist schliesslich eine Basisfertigkeit auch 
wenn man im Einzelfall bessere Lösungen finden kann, wie hier mit dem 
Suchen in einer Datei in dem man eine zeichenweise Verarbeitung darauf 
ansetzt.

: Bearbeitet durch User
von cccccc (Gast)


Lesenswert?

na klar, bei uns wurde das auch nie so streng gehandhabt.
außerdem erkennt man doch sowieso sofort, ob es einer drauf hat oder 
nicht.

die lehrer waren froh wenn die leute zumindest mit einer if-"schleife" 
umgehen konnten ;-)

von Karl H. (kbuchegg)


Lesenswert?

cccccc schrieb:
> na klar, bei uns wurde das auch nie so streng gehandhabt.
> außerdem erkennt man doch sowieso sofort, ob es einer drauf hat oder
> nicht.
>
> die lehrer waren froh wenn die leute zumindest mit einer if-"schleife"
> umgehen konnten ;-)

Ich wär da oben schon froh, wenn er das Programm beenden würde, wenn er 
feststellt, dass er die Datei nicht aufkriegt und nicht einfach weiter 
macht als wäre nichts geschehen. :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.