I'm pretty much new to using files, so I'm not sure if this is a banale question.

Here's the assignment: "Each line of the file dec.txt contains a whole number (>0). Write a program that creates a file called hex.txt. Each line of this file is to contain a string representing the hexadecimal equivalent of the whole number in the corresponding line of dec.txt."

Can someone please walk me through this?

C or C++?

This will load the hex values from smallest to largest:

make a character array ([I]hexval[/I]) about 10 characters long
set whole array to spaces
set [I]hexval[9][/I] to '\0'
set [I]hexptr[/I] to 8 -- this will point into [I]hexval[/I] to load the hex chars.
Read a line into an integer ([I]intval[/I]) -- that's base 10.
Loop until that integer is 0:
    set [I]hexval[hexptr][/I] = [u]remainder[/u] of [I]intval[/I]/16 
    add 48 ('0') to [I]hexval[hexptr][/I]  -- this converts the integer value to a digit character
    if [I]hexval[hexptr][/I] > 57 ('9') add 7 -- value is now 'A' - 'F'
    decrement [I]hexptr[/I]  -- to load the next hex digit
    divide 16 from [I]intval[/I] -- to remove the hex val we just loaded
    End of loop

C, not C++. Sorry, I should have said in the first place.

you can use fscanf("%d", ...) to read them into an int memory, and fprintf("%X" ...) to write them back out as hex.

commented: Way too nonchalant and broad. +0

Yes, it's fairly obvious that can be used. Iguess my question wasn't very to-the-point. Here's what I got so far, and what I need from you:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char dek_hex(int);         /*a function I'll explain later*/
main(){
FILE *a,*b;
int broj;
a=fopen("C:\\C_fajlovi\\deci.txt","r");         /*created a file in the specified directory, it's all cool at this point*/
b=fopen("C:\\C_fajlovi\\hex.txt","w");             /*create a new file to write to*/
while(fscanf(a,"%d",&broj)!=EOF)
 fprintf(b,"%s",&dek_hex(broj));        /*dek_hex should be a function that turns a dec number into hexadecimal and returns it in the form of a string*/
fcloseall();
}
char dek_hex(int m){             /*this is where my problems start. No matter how I write the function, I keep getting all kinds of error messages*/

So my questions would be:

1. is my general idea alright?
2. what should my function look like?
3. can it be done without a function?

Okay here are a few pointers:

1. Use int main( ) not just main( ) and append a return 0 stmt at the end of main( ).

2. Dont hard code the file names in the function, its not a good practice. Just keep the file name in a constant array of characters.

3. I am not sure on this one, but, dont use \\ in your file paths, it is not cross platform complaint. Use forward slashes instead ( / ).

4. After opening the files do check whether the operation is successful, it is a good practice.

FILE* fp ;
if( ( fp = fopen( "a.txt", "r" ) ) == NULL )
{
     fputs( "file opening failed", stderr ) ;
     exit( 1 ) ;
}

5. fscanf( ) normally returns the number of items scanned and in the case of error a NULL is returned.

Member Avatar for iamthwee

>char dek_hex(int m)

You do realise that would return a single char. Is that what you want.

like I mentioned in my previous post, printf() family of functions, which includes ssprintf(), will convert int to hex using "%X" . Example:

char buf[20];
int i = 16;
sprintf(buf,"%x",i);

If you use that in dek_hex() you will have to change the return value from char to char* because as you can see from the above code snippet the hex value is an array of characters, not a single character value.

like I mentioned in my previous post, printf() family of functions, which includes ssprintf(), will convert int to hex using "%X".

I'm not supposed to use any functions I'm not familiar with because I can't use them at my exam either. And my teacher never mentioned ssprintf, all I know out of that family is printf and fprintf.

If you use that in dek_hex() you will have to change the return value from char to char* because as you can see from the above code snippet the hex value is an array of characters, not a single character value.

Yes, I'll do that. That was stupid of me.

you could google for your question. Here is one way to do it. And another here.

So my questions would be:

1. is my general idea alright?

Yes. But you should pass in the hex array. C cannot return a character array. Also, format your code. Indentation is extremely important at all times. So is spacing between terms, like:

while (fscanf(a, "%d", &broj) != EOF)

Much easier to read.

char dek_hex(int m){    /* this is where my problems start. No matter
                           how I write the function, I keep getting all 
                           kinds of error messages */

Unless you post something you've tried, we have nothing to help with.

2. what should my function look like?

Basic idea in my previous post.

3. can it be done without a function?

Yes it can. Considerations:
function: Modularizes the program, easier to reuse the function in another program later. Somewhat easier to debug.
non-function: Not passing the hex array is a minor benefit.

like I mentioned in my previous post, printf() family of functions, which includes ssprintf(), will convert int to hex using "%X" .

Wouldn't this nullify the purpose of understanding how decimal to hex works? ;)

commented: Well said Mr. WaltP -- ~s.o.s~ +7

OK, nevermind, I figured it out. I threw out the function and just did the whole conversion from dec to hex in the body of 'fscanf' with local variables. I realized using a function was a completely pointless complication.

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void main(){
FILE *c,*b;
int a;
c=fopen("C:\\C_fajlovi\\dec.txt","r");
b=fopen("C:\\C_fajlovi\\hex.txt","w");
if (c==NULL){
puts("Error!");
exit(1);
}
if (b==NULL){
puts("Error!");
exit(1);
}
while (fscanf(c,"%d",&a)!=EOF){
 char s[30],temp;
 int i=0;
 if (a==0)
  s[i++]='0';
    while (a>0){                                    /*turning a dec (int) to a hex (string) value*/
        if ((a%16)<=9)
         s[i++]=(a%16)+'0';
        else if ((a%16)==10)
         s[i++]='A';
        else if ((a%16)==11)
         s[i++]='B';
        else if ((a%16)==12)
         s[i++]='C';
        else if ((a%16)==13)
         s[i++]='D';
        else if ((a%16)==14)
         s[i++]='E';
        else
         s[i++]='F';
        a/=16;
        }
    s[i]='\0';                 /*I was missing this part the last time, which is one of the reasons the whole program was acting crazy*/
    for (i=0;i<strlen(s)/2;i++){
     temp=s[i];             /*got a reversed string, turning it around*/
        s[i]=s[strlen(s)-i-1];
        s[strlen(s)-i-1]=temp;
        }
        fprintf(b,"%s\n",s);
    }
}

If someone has any suggestions they're still welcome.

>>while (fscanf(c,"%d",&a)!=EOF){

fscanf() does NOT return EOF one eod-of-file. EOF is returned only if there was a conversion error. What you want is this:

while (fscanf(c,"%d",&a) > 0){

>>while (fscanf(c,"%d",&a)!=EOF){

fscanf() does NOT return EOF one eod-of-file. EOF is returned only if there was a conversion error.

My thought: the while(fscanf... loop would go through the file line by line untill it gets to EOF, at which point it will stop. It works just fine in every program I write (including the one I posted), never had a problem with that.

What will fscanf return when it gets to the end? What you suggested works too, so I suppose it returns 0, but how come my version always works, then?

Because EOF is actually a maro which is defined in stdio.h as #define [B]EOF[/B] [I]<integer constant expression < 0>[/I]

The macro yields the return value used to signal the end of a stream or to report an error condition

In your case its the end of stream thing which is causing the break of loop.
In Mr. Dragons case it is the 0 which is returned by the fgets( ) which is causing the termination.

Here is an example that will illustrate the difference between using EOF and 0. In this example, checking for EOF causes infinite loop because end-of-file is never reached due to conversion error. If you uncomment the while statement that check for 0 then the program will stop when conversion error occurs.

When you wrote your programs for school you probably wrote sample data files that did not contain errors. That will not always be the case in real-world.

#include <stdlib.h>
#include <stdio.h>
 
int main(int ac, char** av) 
{
	int a;
	int counter = 0;
	FILE* fp = fopen("myfile.txt","r");
	if(fp != NULL)
	{
		while( fscanf(fp,"%d",&a) != EOF)
//		while( fscanf(fp,"%d",&a) > 0)
		{
			printf("%d\n",counter++);
		}
		fclose(fp);

	}
	return 0;
}

This is sample data file

1
2
40
abc
5a

Ah, I see what you mean. Had to put a 'getchar()' after 'fclose' though so the black screen would stay open more than a milisecond.

Thanks for the answers.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.