/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
[C] underlige meddelser ?
Fra : Mads Jensen


Dato : 24-04-04 21:02

Hej

Jeg har skrevet et lille C-program, der skriver en fils indhold ud på
skærmen sammen med liniernes numre, men der er bare en lille fejl i det,
ser det ud som (programmet kompilerer perfekt med "gcc -Wall ....").

Jeg får disse meddelser, når jeg kører programmet med:
"pointer pointer.c":

4766: symbol=fclose; lookup in file=pointer
4766: symbol=fclose; lookup in file=/lib/libc.so.6
4766: symbol=fclose; lookup in file=pointer
4766: symbol=fclose; lookup in file=/lib/libc.so.6
lookup 0x08048000 0x00000204 -> 0x40027000 0x00064d30 /1 fclose
4766: symbol=free; lookup in file=pointer
4766: symbol=free; lookup in file=/lib/libc.so.6
4766: symbol=free; lookup in file=/lib/ld-linux.so.2

Programmet er som følger:

--
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[])
{
   char *buffer;
   int line=0;

   if (argc == 1) {
      fprintf(stdout,"Usage: writeout <file> [lines]\n");
      fprintf(stdout,"Type in a filename to continue: ");
      /* this is not really being used for anything, so return 0; */
      /* make a system call to cat as a emergeny */
      return 0;
   }
/* proceed, as if-loop ended with return statement */
   
   FILE *fd;
   fd = fopen(argv[1],"r");
   
   if(!fd){
      fprintf(stderr,"It seems there was an error opening the file!\nError
message returned: ");
      printf("%s\n",strerror(errno)); /* print the variable assigned as the
laste rror msg in <errno.h> */
      exit(1); /* end the program */
   }
   
   while(fgets(buffer,1024,fd) != NULL){ /* buffer contains newline
character, so no need to load that */
    line++;
    printf("%d\t: %s",line,buffer);
   }
   
   fclose(fd);
   return 0;
}

--

Mange tak for hjælpen på forhånd!

mvh.
Mads
--
Mads Jensen - http://www.ddfr.dk
I have not got a suspicious email!

Flon's Law:
   There is not now, and never will be, a language in which it is
the least bit difficult to write bad programs.

 
 
Bertel Brander (24-04-2004)
Kommentar
Fra : Bertel Brander


Dato : 24-04-04 22:24

Mads Jensen wrote:
> Hej
>
> --
> #include <stdlib.h>
> #include <stdio.h>
> #include <fcntl.h>
> #include <sys/stat.h>
> #include <unistd.h>
> #include <sys/types.h>
> #include <string.h>
> #include <errno.h>

En del unødvendige ikke standard header-filer

>
> int main(int argc, char *argv[])
> {
> char *buffer;

Problemet er her, du afsætter ikke plads til at læse linierne ind i.
En hurtig løsning kunne være at erstatte ovenstående med:
char buffer[1024];

> int line=0;
>
> if (argc == 1) {

Hvad sker der hvis brugeren angiver 2 filer som parameter?

/b

Byrial Jensen (25-04-2004)
Kommentar
Fra : Byrial Jensen


Dato : 25-04-04 18:11

Mads Jensen wrote:
> #include <stdlib.h>
> #include <stdio.h>
> #include <fcntl.h>
> #include <sys/stat.h>
> #include <unistd.h>
> #include <sys/types.h>
> #include <string.h>
> #include <errno.h>

Så vidt jeg lige kan se, har du kun brug for at inkludere <stdlib.h>,
<stdio.h>, <string.h> og <errno.h>

> int main(int argc, char *argv[])
> {
> char *buffer;
> int line=0;
>
> if (argc == 1) {
> fprintf(stdout,"Usage: writeout <file> [lines]\n");
> fprintf(stdout,"Type in a filename to continue: ");
> /* this is not really being used for anything, so return 0; */
> /* make a system call to cat as a emergeny */

Øh?? Det er normalt godt med kommentarer, men dog kun hvis de er
forståelige og rimeligt fornuftige. Jeg fatter ikke ovenstående
kommentar ...

> return 0;
> }
> /* proceed, as if-loop ended with return statement */

Ditto.

>
> FILE *fd;
> fd = fopen(argv[1],"r");

UPS! argc kan have værdien 0 hvilken i givent fald vil medføre at din
brug af argv[1] giver udefineret adfærd.

> if(!fd){
> fprintf(stderr,"It seems there was an error opening the
> file!\nError message returned: ");
> printf("%s\n",strerror(errno)); /* print the variable assigned
> as the laste rror msg in <errno.h> */

UPS! errno som sat af fopen(), kan være ændret af fprintf(). Gem altid
errno i en lokal variabel før der laves flere bibliotekskald hvis
værdien ikke kan bruges med det samme.

Hvorfor skriver du første del af meddelelsen til stderr og anden del til
stdout?

> exit(1); /* end the program */

Hvorfor ikke bare "return 1;"? Eller omvendt hvorfor brugte du return
overfor hvis du insisterer på at bruge exit()?

> }
>
> while(fgets(buffer,1024,fd) != NULL){ /* buffer contains newline
> character, so no need to load that */

UPS! buffer er en uinitialiseret pointer. Du indlæser til en ikke-sat
adresse hvilket giver udefineret adfærd.

> line++;
> printf("%d\t: %s",line,buffer);

UPS! Selv hvis buffer havde været et array af 1024 char, ville du ikke
kunne vide om indholdet var NUL-termineret, så du ville risikere
bufferoverløb som giver udefineret adfærd.

> }
>
> fclose(fd);
> return 0;
> }



Bertel Brander (25-04-2004)
Kommentar
Fra : Bertel Brander


Dato : 25-04-04 18:38

Byrial Jensen wrote:
>> while(fgets(buffer,1024,fd) != NULL){ /* buffer contains
>> newline character, so no need to load that */
>
>
> UPS! buffer er en uinitialiseret pointer. Du indlæser til en ikke-sat
> adresse hvilket giver udefineret adfærd.
>
>> line++;
>> printf("%d\t: %s",line,buffer);
>
>
> UPS! Selv hvis buffer havde været et array af 1024 char, ville du ikke
> kunne vide om indholdet var NUL-termineret, så du ville risikere
> bufferoverløb som giver udefineret adfærd.
>

Er du sikker på det?

Ifølge C standarden:

"The fgets function reads at most one less than the number of characters
specified by n from the stream pointed to by stream into the array
pointed to by s. No additional characters are read after a new-line
character (which is retained) or after end-of-file. A null character is
written immediately after the last character read into the array."

/b

Byrial Jensen (25-04-2004)
Kommentar
Fra : Byrial Jensen


Dato : 25-04-04 19:04

Bertel Brander wrote:
> Byrial Jensen wrote:
>
>>> while(fgets(buffer,1024,fd) != NULL){ /* buffer contains
>>> newline character, so no need to load that */
>>
>>
>> UPS! Selv hvis buffer havde været et array af 1024 char, ville du ikke
>> kunne vide om indholdet var NUL-termineret, så du ville risikere
>> bufferoverløb som giver udefineret adfærd.
>
> Er du sikker på det?

Nej, min udtalelsen er forkert. Det man ikke kan være sikker på med
fgets(), er om der er indlæst et linjeskift ('\n'). Det er ikke i sig
selv et problem i Mads' program ud over at kommentaren i begyndelsen af
while-blokken er misvisende og sikkert har forvirret min tankegang. Jeg
beklager fejlen.


Søg
Reklame
Statistik
Spørgsmål : 177580
Tips : 31968
Nyheder : 719565
Indlæg : 6409076
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste