Mit C vernünftig Strings eingeben und auslesen

meisteralex

Lieutenant
Registriert
Juni 2003
Beiträge
552
Hi Leute, wie kann ich mit
printf und scanf vernünftig String einlesen, ohne das Sie z.B. nur bis zum ersten Leerzeichen eingelesen werden.
Bekomm hier nochma die Kriese, also wär nen Codebeispiel wäre cool!
thx
 
Mit scanf garnicht. scanf ist für formatierten Input gemacht - und dieser wird durch Whitespaces getrennt. Du könntest mit getchar arbeiten und selber parsen.
 
Hallo,

Du kannst entweder scanf sagen bis wohin er einlesen soll, das ginge z.B. so:
Code:
#include <stdio.h>
#include <string.h>

int main(){
	char s[512];
		
	printf("String eingeben: ");
	scanf("%[^'\n']",&s); //in eclipse sind die letzten Zeichen '\n' und '\0' sonst nur '\0'
	printf("\nEingabe war: %s \n",s);
	
	return 0;
}

Oder du benutzt
Code:
gets(s);
aus der string Bibliothek, welches einen Satz bis zum Drücken der Eingabetaste einliest.

mfg
 
scanf("%[^'\n']",&s);
Interessant. Habe das gerade mal im ISO9899 nachgeschlagen; wusste garnicht (und hätte nicht erwartet), dass das Standard-C ist. Aber man lernt nie aus. :) (dann revidiere ich natürlich meinen oberen Post ;))
 
Zuletzt bearbeitet:
Und wie siehts mit

Code:
#include <stdio.h>
#include <string.h>
#include <conio.h>

void main(void)
{
    char s[512];
        
    cout << "String eingeben: ";
    cin >> s;
    cout << endl << "String ist: " << s;
}
aus? Ist doch die super Laien-Methode :D
Ist aber glaube nicht Standardkonform und nur für den C-Builder.
 
@AndrewPoison: Das ist kein C(++)-Builder eigenes Konstrukt, sondern entspricht der Ansi-C++ Streamverarbeitung ...
 
Kenn mich in C noch nicht so gut aus, bin erst beim erlernen ^^
 
AndrewPoison schrieb:
Code:
#include <stdio.h>
#include <string.h>
[color=red]#include <conio.h> // Den Header gibt's nur unter Windows[/color]

[color=red]#include <iostream> // wird für cout gebraucht, ist aber C++ und kein C
using namespace std; // damit man cout anstatt std::cout schreiben kann[/color]

[color=red]void[/color] main(void) // es gibt nur int main
{
    char s[512];
        
    cout << "String eingeben: ";
    cin >> s;
    cout << endl << "String ist: " << s;
}

Ist aber glaube nicht Standardkonform und nur für den C-Builder.

Die nicht-standardkonformen Teile habe ich mal markiert. Aber cout ist C++, aber der Autor will C haben. ;) Und das würde auch nach einem Leerzeichen aufhören zu lesen.
 
1.) Wenn wir einmal ganz genau sind, dass gibt es in C auch kein //, sondern nur /* und */.

2.) Dass Linux kein conio.h unterstützt, macht das Ganze um etliches umständlicher, aber du kannst ja einfach in einer Schleife immer mit scanf einlesen, solange bis du ein \n hast.
 
Mal nebenbei: In C++ würd ich eh nur Strings nehmen statt char arrays ;)

Lösungen für C wurden ja schon zur Genüge gepostet.
 
Schön. Ein Thread wo man ein bissl spitzfindig sein darf :).

@andr_gin
Ab ISO/IEC 9899:1999 (kurz C99) sind auch // Kommentare in C zulässig (Kapitel 6.4.9 Comments auf Seite 66 des Standards).
 
Zuletzt bearbeitet:
@Sisko
Auch wenn void main(){} erlaubt sein mag, ist es eine sehr schlechte Angelegenheit, die gegen den Baum geht, wenn man Pech hat... Deswegen immer int main(){}

edit: Mal schnell in der Iso C99 nachgeschlagen:
In 5.1.2.2.1
The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters
[...]
5.1.2.2.3
If the return type of the main function is a type compatible with int, a return from the
initial call to the main function is equivalent to calling the exit function with the value
returned by the main function as its argument;10) reaching the } that terminates the
main function returns a value of 0. If the return type is not compatible with int, the
termination status returned to the host environment is unspecified
.[...]

Insbesondere der Annex J (Portability issues):
The following are unspecified:
[...]
— The termination status returned to the hosted environment if the return type of main
is not compatible with int (5.1.2.2.3).
[...]

M.a.W.: Lasst die Finger von void main(){} !
 
Zuletzt bearbeitet:
-Sisko- schrieb:
@7H3 N4C3R
laut standard gibt es void main(){} genauso wie int main(){}

Dann trete bitte den Beweis an mit Dokument, Paragraph und Absatz an.

(das wird dir nicht gelingen, void main war noch nie Standard, weder C89 (mit oder ohne 94-Erweiterungen), C99, C++98 noch C++2003)


Zusätzlich zu Götterwinds Ausführungen noch das hier (aus ISO9899, betrifft genauso ISO14882 (C++)):
4.1) In this International Standard, ‘‘shall’’ is to be interpreted as a requirement on an
implementation or on a program; conversely, ‘‘shall not’’ is to be interpreted as a
prohibition.

"shall" heißt also nicht "sollte", sondern es muss so sein. Damit ist mit 5.1.2.2.1 (oder 3.6.1 in ISO14882) alles gesagt.
 
Zuletzt bearbeitet:
Na wenn schon muss der Paragraph 5.1.2.2.1 ganz zitiert werden (siehe auch hier):

The function called at program startup is named main. The implementation declares noprototype for this function. It shall be defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent; or in some other implementation-defined manner.

Wenn dein Compiler also void main() als gültig definiert dann kannst du ganz im Sinne des Standards auch void main() verwenden.

Natürlich sollte man der Portabilität wegen trotzdem immer int main() verwenden.
 
Das ändert trotzdem nichts an 5.1.2.2.3
5.1.2.2.3 Program termination
1 If the return type of the main function is a type compatible with int, a return from the
initial call to the main function is equivalent to calling the exit function with the value
returned by the main function as its argument;10) reaching the } that terminates the
main function returns a value of 0. If the return type is not compatible with int, the
termination status returned to the host environment is unspecified.

Und das ändert auch nichts an Annex J ;) Eine Main-Funktion mit "void" zu deklarieren wird immer zu einem unkontrollierbaren Verhalten führen.

Da man heutzutage eh kaum reine C-Compiler nutzt, ist die Diskussion eh meist hinfällig, da es in C++ eh nicht erlaubt ist, void main () {} zu nutzen.
 
Zuletzt bearbeitet:
5.1.2.2.3 sagt aber doch durch die Fallunterscheidung zwischen int main() und nicht int main() recht deutlich, dass beide Fälle möglich sind (ansonsten müsste ja nur etwas über int main() ausgesagt werden).

Und auch Annex J macht nur Sinn wenn void main() nicht verboten ist, denn warum sollte der Standard in diesem Fall explizit erwähnen, dass die Verwendung von etwas Verbotenem zu unspezifiziertem Verhalten führt.

Meiner Meinung nach sind durch 5.1.2.2.1 also auch beliebige implementationsspezifische Versionen von main erlaubt, aber laut 5.1.2.2.3 und Annex J ist der Rückgabewert an den Aufrufer in diesen Fällen offensichtlich nicht standardisiert und hängt somit vom verwendeten Compiler ab. Damit ist klar, dass man int main() verwenden sollte, man muss aber nicht.
 
Richtig-da steht, dass der Rückgabewert zu int kompatibel sein muss. Es muss nicht int sein. Wenn jetzt in deiner Umgebung sich ein anderer Typ wie int verhält, dann ist das ja ok. Aber das tut es ja in den meisten Fällen nicht, insbesondere void...

Naja, wir schweifen etwas vom deutlich vom Thema ab.
 
Ihr habt einen totalen Schaden!

Es ist doch eigentlich recht egal, ob es nun ganz sicher Standard ist oder nicht. Wir könnten uns doch einfach darauf einigen dass man es halt macht weil es sich nunmal so gehört.

Wie die Politiker hier. Oder Anwälte. ;)

Jetzt hab ich euh beleidigt. Das habt ihr nun davon! :p
 
Zurück
Oben