Avatar billede Slettet bruger
08. marts 2004 - 09:42 Der er 6 kommentarer og
3 løsninger

Hvorfor virker denne kode ikke?

Hvorfor virker nedenstående kode ikke for mig, jeg får en windows fejl hver gang jeg afvikler koden.

og hvad funktion har linien    tekst[strlen(tekst)-1] = '\0';??


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

int main()
{
  FILE *fp;
  char line[10],tekst[10];           
  int tala,talb;
 
  fp = fopen("test.txt", "r");
                               
  while(!feof(fp))                       
  {
    fgets(line,sizeof(line),fp);
    strcpy(tekst,line);                   
    tekst[strlen(tekst)-1] = '\0';
    fgets(line,sizeof(line),fp);
    tala = atoi(line);                   
    fgets(line,sizeof(line),fp);       
    talb = atoi(line);                   
    fgets(line,sizeof(line),fp);       
    cout <<tekst << tala << talb;       
  }

  fclose(fp);                           
  return 0;
Avatar billede segmose Nybegynder
08. marts 2004 - 10:16 #1
Der er indtil flere potentielle fejl, der testes ikke om fp er NULL, dvs. hvis filen ikke findes fejler programmet groft.
hvis linierne er længere end line overskriver
tekst[strlen(tekst)-1] = '\0';
det sidste tegn i tekst, ellers ville den fjerne linefeed.
atoi er ikke sikret mod overflow.
Avatar billede Slettet bruger
08. marts 2004 - 10:19 #2
okay, hvordan ser koden ud så det virker? JEg kan ik lige få den til det :(

Filen findes men skal selvfølgelig også sikres mod dette.
Avatar billede segmose Nybegynder
08. marts 2004 - 10:39 #3
int main() {
  FILE *fp;
  char line[11],tekst[11];          // mindst 11 tegn, 1000000000 + afsluttende '\0'
  int tala,talb;

  fp = fopen("test.txt", "r");
  if (!fp) {
    cout << "filen kan ikke åbnes\n";
    return EXIT_FAILURE;
  }
                               
  while(!feof(fp)) {
    fgets(line,sizeof(line),fp);
    strcpy(tekst,line);                 
    tekst[strlen(tekst)-1] = '\0'; // her er ikke så meget at gøre andet end at lave mere plads eller læse ind i en std::String.
    fgets(line,sizeof(line),fp);
    tala = atoi(line);      // atoi returnere bare 0 hvis den ikke forstår, brug sscanf istedet, evt. << men der mangler også noget.           
    fgets(line,sizeof(line),fp);     
    talb = atoi(line);                 
    fgets(line,sizeof(line),fp);     
    cout <<tekst << tala << talb;     
  }

  fclose(fp);                         
  return 0;
}
Avatar billede Slettet bruger
08. marts 2004 - 11:00 #4
Får følgende fejl, men den cout lavede også lort i den udgave jeg skrev herover!!

error C2065: 'cout' : undeclared identifier
error C2297: '<<' : illegal, right operand has type 'char [22]'
error C2297: '<<' : illegal, right operand has type 'char [11]'
Avatar billede segmose Nybegynder
08. marts 2004 - 12:30 #5
tilføj enten efter dine include
using std::cout;
eller skriv
std::cout<<tekst << tala << talb;
Avatar billede Slettet bruger
08. marts 2004 - 12:57 #6
Nu ser det ud til at virke.. men forstår stadig ikke helt linien:

tekst[strlen(tekst)-1] = '\0';

Hvad er det den laver?
Avatar billede the_bma_man Nybegynder
08. marts 2004 - 19:49 #7
I c og c++ er en streng (eller helt korrekt - et array af tegn) defineret som en pointer til den første karakter - og så slutter strengen, når der mødes en karakter 0 ('\0')
Den sættes for at sikre, at din streng er afsluttet. Ellers vil du begynde at læse ind i memory, som du ikke har allokeret - og sikkert fp en access violation.
Det lille karakter 0 er også grundet til, at du altid skal definere dine strenge een byte større, end de faktisk skal indholde. Så en char str[10] kan altså indeholde en streng på 9 tegn + det afsluttende karakter 0 ('\0')
Avatar billede segmose Nybegynder
08. marts 2004 - 20:13 #8
the_bma_man: det er rigtigt nok, men fgets sikre faktisk at du få den afsluttende '\0':
Citat:
"fgets reads characters from stream into the string s. The function stops reading when it reads either n - 1 characters or a newline character whichever comes first. fgets retains the newline character at the end of s. A null byte is appended to s to mark the end of the string."

Så det den gør i dette tilfælde er at fjerne det afsluttende '\n' istedet, du kan overvej hvad strlen(tekst) returnere hvis den ikke var afsluttet med '\0'...
Men hvis teksten der bliv læst ind var længere end 9 char ville der ikke være en '\n' at fjerne, men en af char'ne ville blive overskrevet ex. filen indeholder linien:
123456789ABCDEF
så vil
fgets(line,sizeof(line),fp);
indlæse
"123456789\0" i line, som så kopieres til tekst
hvorefter
tekst[strlen(tekst)-1] = '\0'; // strlen er her 9, index 8 overskrives.
vil få indholdet af tekst til at blive
"12345678\0\0"
bemærk at 9 tallet bliv overskrevet da det stod på tekst[8].
Hvis filen derimod indeholdt
"12345678\n" ville line indeholde
"12345678\n\0" som så kopieres til teskt hvor
tekst[strlen(tekst)-1] = '\0';
betyder at vi får:
"12345678\0\0"
Avatar billede the_bma_man Nybegynder
08. marts 2004 - 20:36 #9
Hep - det ved jeg godt.
Men nu spurgte manden jo helt konkret, hvad den linie var til :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester