Suchen und ersetzen?

Ascanius

Grünschnabel
Hiho erstmal, ich hab ein kleines Problem mit einem C-Programm.

Also die Aufgabe vom Programm sieht erstmal wie folgt aus:

Schreiben Sie ein Programm expand, das als Kommandozeilenparameter einen Dateinamen erwartet. Der Inhalt dieser Datei soll zur Standardausgabe kopiert werden. Dabei ist aber jeder Tabulator (in C dargestellt durch '\t') in die entsprechende Anzahl Leerzeichen umzuwandeln.
Wird kein Dateiname angegeben, ist die Standardeingabe als Eingabe zu verwenden.


Mein programm kann die Datei lesen und den text auch ausgeben allerdings bräuchte ich jetzt noch etwas was den textchar durchsucht und die \t die im text eingetippt sind in die entsprechende escapesequenz umgewandelt werden. Das suchen würde ich warscheinlich noch hinbekommen (dafür haben wir früher mal ein programm geschrieben) allerdings habe ich keine ahnung wie ich den text dann gegen die Escapesequenz auswechseln kann.

Mein Programm:

#include<stdio.h>


main(int argc,char *argv [] ){
int a;
char text[100] ;
FILE *dateiptr;
if (argc<2)
printf("Es fehlt der Dateiname");
else{
dateiptr=fopen(argv[2],"r");

if (dateiptr!=NULL) {
printf("\nDatei ist vorhanden und wurde geoeffnet\n");
fscanf (dateiptr, "%100c", text);
printf("%s",text);

}

else
printf("%s",argv[2]);

}



}

Ein weiteres problem ist noch wenn ich den Text ausgebe kommen danach noch ein paar komische für mich nicht zuzuordnende buchstaben.

Wenn jmd mir helfen kann wär ich dankbar!
 
Hi.

Bitte verwende die Code-Tags!

Von welches Escapesequenzen sprichst du? Du mußt doch nur statt einem Tabulatorzeichen acht Leerzeichen ausgeben.

Mit der Funktion strchr kannst du ein Zeichen in einem String finden. Wenn also ein Tabulatorzeichen gefunden wird, gibst du einfach den Teil vor dem Tabulatorzeichen aus und schreibst noch 8 Leerzeichen statt des Tabulatorzeichens auf die Standardausgabe. Dann verarbeitest du den restlichen String ohne das gefundene Tabulatorzeichen.

Die Zeichen die dort zusätzlich ausgegeben werden resultieren aus der Tatsache, das mit dem Formatstring "%100c" max. 100 Zeichen eingelesen werden, der String aber nicht terminiert wird. Du weißt also nicht wieviel Zeichen überhaupt gelesen wurden und es ist reiner Zufall, das das Programm dann nicht abstürzt.

Warum liest du nicht einfach zeichenweise ein?

Gruß
 
Code-Tags ? (sry bin neu hier im forum^^ )

Das problem das der Tabulator ja auf die nächste durch acht teilbare stelle, und nicht acht zeichen einrückt.

und \t sind ja 2 und nicht ein zeichen die gesucht werden muss. Mit dem zeichenweisen einlesen ja ich hab in c leider nicht ganz so den durchblick. Wie das programm bis jetzt ist habs ichs hinbekommen, bin für tipps immer offen. Wie könnte ich das mit dem zeichenweise einlesen dann am besten machen? Weil der text muss ja entweder in den komandozeilenparameter eingegeben werden oder eine externe textdatei darüber eingelesen werden.

Gruß Ascanius
 
Code-Tags ? (sry bin neu hier im forum^^ )
Du schreibst deinen Code innerhalb von [c]...[/c] für C, [code=cpp]...[/code] für C++ usw.
Das problem das der Tabulator ja auf die nächste durch acht teilbare stelle, und nicht acht zeichen einrückt.
Aha, das war mit "in die entsprechende Anzahl Leerzeichen" umwandlen gemeint.

Dann müßtest für jede Zeile, die Zeichen zählen die bereits ausgegeben wurden und falls du auf ein Tabulatorzeichen triffst, entsprechend die Anzahl Leerzeichen noch ausgeben, die noch fehlen.
und \t sind ja 2 und nicht ein zeichen die gesucht werden muss.
Nein, das ist falsch. Ein \t ist ein Zeichen:
C:
char tab = '\t'; // ein Tabulatorzeichen.
Mit dem zeichenweisen einlesen ja ich hab in c leider nicht ganz so den durchblick. Wie das programm bis jetzt ist habs ichs hinbekommen, bin für tipps immer offen. Wie könnte ich das mit dem zeichenweise einlesen dann am besten machen? Weil der text muss ja entweder in den komandozeilenparameter eingegeben werden oder eine externe textdatei darüber eingelesen werden.
Laut Aufgabenstellung sollst du eine Datei lesen. Bisher liest du von dieser Datei max. 100 Zeichen.

Zeichenweise kannst du mit der Funktion fgetc und zeilenweise mit der Funktion fgets einlesen. Such mal hier im Forum, das hatten wir erst vor ein paar Tagen.

Gruß
 
Ah das hat mich schonmal nen stücken weiter gebracht aber mit strchr komm ich noch nicht so klar.

C:
#include<stdio.h>
#include<string.h>


main(int argc,char *argv [] ){
	int a=0;
	char cZeichen[a];
    char tab = '\t';
	FILE *dateiptr;
	if (argc<2)
		printf("Es fehlt der Dateiname");
	else{
		dateiptr=fopen(argv[2],"r");
		
        if (dateiptr!=NULL) {
		printf("\nDatei ist vorhanden und wurde geoeffnet\n");
while ((cZeichen[a] = fgetc(dateiptr)) != EOF) {
    putchar(cZeichen[a]);
    a++;
}

  
  
	while (cZeichen[a] != EOF) {
          	printf("%s",cZeichen[a]); 
           a++; }
	

		}

		else
			printf("%s",argv[2]);
		
		}

}

jetzt lese ich die zeichen ja zeichenweise ein (zumindest wenn man einen externen text nimmt).
Ich hab gerade ein bischen zu strchr gegooglet und ein programmbeispiel gefunden welches die stelle ermittelt an dem sich der gesuchte buchstabe befindet.

C:
/* strchr example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] = "This is a sample string";
  char * pch;
  printf ("Looking for the 's' character in \"%s\"...\n",str);
  pch=strchr(str,'s');
  while (pch!=NULL)
  {
    printf ("found at %d\n",pch-str+1);
    pch=strchr(pch+1,'s');
  }
  return 0;
}

etwas in die richtung könnte ich ja dann auch benutzen um zu sehen wie viele stellen vor dem \t zu finden und das dann damit zu machen.

wollte das erstmal so machen das ich auch die stelle des zeichens finde (als ersten schritt) :
C:
    char *pch;
pch=strchr (cZeichen[a],tab );


 while (pch!=NULL)
  {
    printf ("found at %d\n",pch-cZeichen[a]+1);
    pch=strchr(pch+1,'s');
  }

zum einen kriege ich ein warning "passing arg 1 of strchr makes pointer from integer without a cast" und wenn ich das programm starte gibts ne fehlermeldung.
 
C:
#include<stdio.h>
#include<string.h>


main(int argc,char *argv [] ){
	int a=0;
	char cZeichen[a];
    char tab = '\t';
	FILE *dateiptr;
	if (argc<2)
		printf("Es fehlt der Dateiname");
	else{
		dateiptr=fopen(argv[2],"r");
		
        if (dateiptr!=NULL) {
		printf("\nDatei ist vorhanden und wurde geoeffnet\n");
while ((cZeichen[a] = fgetc(dateiptr)) != EOF) {
    putchar(cZeichen[a]);
    a++;
}
Du hättest das ganze Thema lesen sollen, insbesondere den Teil wo ich gesagt habe, das der Code so nicht richtig ist, weil fgetc aus gutem Grund einen int zurückliefert.

Wenn du die Verarbeitung zeichenweise machst, dann brauchst du die Funktion strchr nicht. Deshalb habe ich dir auch vorgeschlagen es zeichenweise zu tun weil es nämlich viel einfacher ist.

Du mußt nur auf 2 spezielle Zeichen achten: das Newline-Zeichen und das Tab-Zeichen. Alle anderen Zeichen zählst du einfach mit, denn wenn du auf ein Tab-Zeichen triffst mußt du ja wissen in welcher Spalte du bist und wieviel Leerzeichen du jetzt ausgeben mußt.
C:
int c;
int spalte = 0;

while ((c = fgetc(dateiptr)) != EOF) {
  if (c == '\n') {
    spalte = 0;
  } else if (c == '\t') {
    // hier Leerzeichen ausgeben und spalte auf richtigen Wert setzen
    ...
  } else {
    ++spalte;
    putc(c);
  }
}
Du kannst das Ganze natürlich auch mit einer switch Anweisung machen. (als kleine Übung :))

Gruß
 
ah sry da hab ich dann was geistig aus deinem post durchnandergeworfen.

aber ich hab nur noch so ein kleines verständnissproblem. fgetc liefert mir einen integer also eine ganzzahl gibt dann die stelle an an dem jeweils ein char ist? dann müsste aber doch theoretisch \ und t 2 zeichen sein, wie kann man dann c=='\t' abfragen? (entschuldige bitte wenn die frage zu dumm ist ^^kann auch sein das ich gerade mal nen riesen brett vorm kopf hab)

aber wenn das so ist das c die jeweilge stelle angibt müsste ich ja dann im else if teil dann etwas einbauen was (c-1) modulo 8 macht und dementsprechend viele leerzeichen einbaut ?

ich hab mal deinen quelltext reinkopiert und der meldet mir bei putc "too few arguments to function 'putc' (putchar funktionier aber wo liegt der unterschied?!)
 
Hi.

Ist deine Umschalt-Taste kaputt? ;-] Bitte beachte die Netiquette (steht groß über dem Nachrichteneditor!).
aber ich hab nur noch so ein kleines verständnissproblem. fgetc liefert mir einen integer also eine ganzzahl gibt dann die stelle an an dem jeweils ein char ist?
Mit dem Satz hab ich Probleme. Was meinst du damit?
dann müsste aber doch theoretisch \ und t 2 zeichen sein,
Nein, warum? Die Funktion fgetc liest ein Zeichen und gibt es als int zurück. Auch ein char ist nur ein Zahlenwert, wobei natürlich jedem dieser Werte auch ein bestimmtes Zeichen zugeordnet ist. Ein char kann (normalerweise) 256 verschiedene Werte annehmen. Wenn man ein Zeichen aus einer Datei liest kann es jeden dieser 256 Werte haben. Welchen Wert sollte man jetzt aber bei einem Fehler oder EOF zurückgeben? Es darf auf keinen Fall ein char Wert sein, denn der könnte ja auch ganz normal in der Datei stehen! Deswegen gibt die Funktion fgetc einen int zurück, denn sie muß 257 verschiedene Werte zurückgeben können.
wie kann man dann c=='\t' abfragen
c ist ein Zahlenwert, '\t' ist auch ein Zahlenwert - die kann man doch vergleichen. Obwohl beide nicht den gleichen Typ haben, aber C kennt "Typpromotion" und wandelt einen untergeordneten Zahlentyp automatisch in den übergeordneten Typ um.
aber wenn das so ist das c die jeweilge stelle angibt
Nein, c gibt nicht die Stelle an. c ist das Zeichen was eingelesen wurde. Die Variable "spalte" gibt die Spalte an.
ich hab mal deinen quelltext reinkopiert und der meldet mir bei putc "too few arguments to function 'putc' (putchar funktionier aber wo liegt der unterschied?!)
Ja, da hab ich was durcheinander geworfen. :) Ich meinte putchar.

Gruß
 
Oh sorry werd versuchen drauf zu achten, ich hab irgentwie so den hang wen ich im Netz unterwegs bin einfach alles so runter zu tippen.
Zitat:
Zitat von Ascanius
aber ich hab nur noch so ein kleines verständnissproblem. fgetc liefert mir einen integer also eine ganzzahl gibt dann die stelle an an dem jeweils ein char ist?
Mit dem Satz hab ich Probleme. Was meinst du damit?
Hat sich durch den rest des Postes geklärt.

Ich hab zwar jetzt noch nicht den Quelltext fertig geschrieben beim else if aber so wie ich den Quelltext von dir kopiert habe gibt der den \t weiterhin aus, das dürfte er ja dann nicht mehr tun wenn ich das richtig verstanden habe oder?

Gruß Ascanius
 
Ich hab zwar jetzt noch nicht den Quelltext fertig geschrieben beim else if aber so wie ich den Quelltext von dir kopiert habe gibt der den \t weiterhin aus, das dürfte er ja dann nicht mehr tun wenn ich das richtig verstanden habe oder?
Richtig. Vermutlich hast du keine echten Tabulator-Zeichen in der Eingabedatei? In der Eingabedatei darfst du nicht einfach \t verwenden. Du mußt schon Tabulatorzeichen (Zeichen 9 der ASCII Tabelle) verwenden.

Gruß
 
Zurück