Using fscanf with a while loop to store a char and int












0














Im am trying to use fscanf to read through a file of hex numbers that either have a char followed by numbers or just numbers and no char. The fscanf appears to work for the first line of the file but that's it.



FILE



E10
20
22
18
E10
210
12


CODE



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

int main(int argc, char** argv) {
FILE * iFile;
char instr;
unsigned long long int address;

iFile = fopen("addresses.txt", "r");
if(iFile != NULL){

while (fscanf(iFile, "%c%x", &instr, &address) > 0){

printf("%c", instr); //This just works for the first line

}

}
fclose(iFile);
return 0;
}









share|improve this question






















  • When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
    – paddy
    Nov 12 at 1:58










  • @paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
    – Matthew
    Nov 12 at 2:04










  • What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of %x. If you stepped through your program with a debugger or added extra outputs (such as what fscanf returns, or the value in address) you might figure out what's happening on your own.
    – paddy
    Nov 12 at 2:16












  • @paddy I figured it out, just had to add a space infront of the first %
    – Matthew
    Nov 12 at 2:21












  • You are using the wrong format specifier, %x is for unsigned int
    – M.M
    Nov 12 at 3:29
















0














Im am trying to use fscanf to read through a file of hex numbers that either have a char followed by numbers or just numbers and no char. The fscanf appears to work for the first line of the file but that's it.



FILE



E10
20
22
18
E10
210
12


CODE



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

int main(int argc, char** argv) {
FILE * iFile;
char instr;
unsigned long long int address;

iFile = fopen("addresses.txt", "r");
if(iFile != NULL){

while (fscanf(iFile, "%c%x", &instr, &address) > 0){

printf("%c", instr); //This just works for the first line

}

}
fclose(iFile);
return 0;
}









share|improve this question






















  • When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
    – paddy
    Nov 12 at 1:58










  • @paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
    – Matthew
    Nov 12 at 2:04










  • What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of %x. If you stepped through your program with a debugger or added extra outputs (such as what fscanf returns, or the value in address) you might figure out what's happening on your own.
    – paddy
    Nov 12 at 2:16












  • @paddy I figured it out, just had to add a space infront of the first %
    – Matthew
    Nov 12 at 2:21












  • You are using the wrong format specifier, %x is for unsigned int
    – M.M
    Nov 12 at 3:29














0












0








0







Im am trying to use fscanf to read through a file of hex numbers that either have a char followed by numbers or just numbers and no char. The fscanf appears to work for the first line of the file but that's it.



FILE



E10
20
22
18
E10
210
12


CODE



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

int main(int argc, char** argv) {
FILE * iFile;
char instr;
unsigned long long int address;

iFile = fopen("addresses.txt", "r");
if(iFile != NULL){

while (fscanf(iFile, "%c%x", &instr, &address) > 0){

printf("%c", instr); //This just works for the first line

}

}
fclose(iFile);
return 0;
}









share|improve this question













Im am trying to use fscanf to read through a file of hex numbers that either have a char followed by numbers or just numbers and no char. The fscanf appears to work for the first line of the file but that's it.



FILE



E10
20
22
18
E10
210
12


CODE



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

int main(int argc, char** argv) {
FILE * iFile;
char instr;
unsigned long long int address;

iFile = fopen("addresses.txt", "r");
if(iFile != NULL){

while (fscanf(iFile, "%c%x", &instr, &address) > 0){

printf("%c", instr); //This just works for the first line

}

}
fclose(iFile);
return 0;
}






c while-loop scanf






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 12 at 1:52









Matthew

25




25












  • When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
    – paddy
    Nov 12 at 1:58










  • @paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
    – Matthew
    Nov 12 at 2:04










  • What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of %x. If you stepped through your program with a debugger or added extra outputs (such as what fscanf returns, or the value in address) you might figure out what's happening on your own.
    – paddy
    Nov 12 at 2:16












  • @paddy I figured it out, just had to add a space infront of the first %
    – Matthew
    Nov 12 at 2:21












  • You are using the wrong format specifier, %x is for unsigned int
    – M.M
    Nov 12 at 3:29


















  • When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
    – paddy
    Nov 12 at 1:58










  • @paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
    – Matthew
    Nov 12 at 2:04










  • What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of %x. If you stepped through your program with a debugger or added extra outputs (such as what fscanf returns, or the value in address) you might figure out what's happening on your own.
    – paddy
    Nov 12 at 2:16












  • @paddy I figured it out, just had to add a space infront of the first %
    – Matthew
    Nov 12 at 2:21












  • You are using the wrong format specifier, %x is for unsigned int
    – M.M
    Nov 12 at 3:29
















When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
– paddy
Nov 12 at 1:58




When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
– paddy
Nov 12 at 1:58












@paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
– Matthew
Nov 12 at 2:04




@paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
– Matthew
Nov 12 at 2:04












What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of %x. If you stepped through your program with a debugger or added extra outputs (such as what fscanf returns, or the value in address) you might figure out what's happening on your own.
– paddy
Nov 12 at 2:16






What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of %x. If you stepped through your program with a debugger or added extra outputs (such as what fscanf returns, or the value in address) you might figure out what's happening on your own.
– paddy
Nov 12 at 2:16














@paddy I figured it out, just had to add a space infront of the first %
– Matthew
Nov 12 at 2:21






@paddy I figured it out, just had to add a space infront of the first %
– Matthew
Nov 12 at 2:21














You are using the wrong format specifier, %x is for unsigned int
– M.M
Nov 12 at 3:29




You are using the wrong format specifier, %x is for unsigned int
– M.M
Nov 12 at 3:29












1 Answer
1






active

oldest

votes


















0














In such cases, where you will be trying to parse the same line many times, it is better to read the line into memory, and then deal with the data in memory, rather than on disk.



char line[MAXLINE];
fgets(line, MAXLINE, iFile);


Then you have what I call the "sscanf ladder," which is a series of if-else if clauses, each of which attempts to parse line in different ways. The condition would examine the return value of sscanf, since the number of objects successfully read is the return value. So we use this number to distinguish among several different formats:



if (sscanf(line, "%c%x", &instr, &address) == 2)
/* you have an instruction and an address */
else if (sscanf(line, "%x", &address) == 1)
/* you have an address only */


Since, in your case, this is a loop condition, you will have to refactor this into a function of its own:



int readAtLeastAddress(const char *const line, char *instr, unsigned long long *address)
{
return sscanf(line, "%c%x", instr, address) == 2 || sscanf(line, "%x", &address) == 1;
}


Then you would rewrite the loop as such



while (readAtLeastAddress(line, &instr, &address)) {
printf("%c", instr);
}





share|improve this answer





















  • Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the %c%x pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something like isalpha or isdigit to test the first character of the line.
    – paddy
    Nov 12 at 3:05










  • You use the wrong format specifier , %x is for unsigned int
    – M.M
    Nov 12 at 3:29











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53255077%2fusing-fscanf-with-a-while-loop-to-store-a-char-and-int%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














In such cases, where you will be trying to parse the same line many times, it is better to read the line into memory, and then deal with the data in memory, rather than on disk.



char line[MAXLINE];
fgets(line, MAXLINE, iFile);


Then you have what I call the "sscanf ladder," which is a series of if-else if clauses, each of which attempts to parse line in different ways. The condition would examine the return value of sscanf, since the number of objects successfully read is the return value. So we use this number to distinguish among several different formats:



if (sscanf(line, "%c%x", &instr, &address) == 2)
/* you have an instruction and an address */
else if (sscanf(line, "%x", &address) == 1)
/* you have an address only */


Since, in your case, this is a loop condition, you will have to refactor this into a function of its own:



int readAtLeastAddress(const char *const line, char *instr, unsigned long long *address)
{
return sscanf(line, "%c%x", instr, address) == 2 || sscanf(line, "%x", &address) == 1;
}


Then you would rewrite the loop as such



while (readAtLeastAddress(line, &instr, &address)) {
printf("%c", instr);
}





share|improve this answer





















  • Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the %c%x pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something like isalpha or isdigit to test the first character of the line.
    – paddy
    Nov 12 at 3:05










  • You use the wrong format specifier , %x is for unsigned int
    – M.M
    Nov 12 at 3:29
















0














In such cases, where you will be trying to parse the same line many times, it is better to read the line into memory, and then deal with the data in memory, rather than on disk.



char line[MAXLINE];
fgets(line, MAXLINE, iFile);


Then you have what I call the "sscanf ladder," which is a series of if-else if clauses, each of which attempts to parse line in different ways. The condition would examine the return value of sscanf, since the number of objects successfully read is the return value. So we use this number to distinguish among several different formats:



if (sscanf(line, "%c%x", &instr, &address) == 2)
/* you have an instruction and an address */
else if (sscanf(line, "%x", &address) == 1)
/* you have an address only */


Since, in your case, this is a loop condition, you will have to refactor this into a function of its own:



int readAtLeastAddress(const char *const line, char *instr, unsigned long long *address)
{
return sscanf(line, "%c%x", instr, address) == 2 || sscanf(line, "%x", &address) == 1;
}


Then you would rewrite the loop as such



while (readAtLeastAddress(line, &instr, &address)) {
printf("%c", instr);
}





share|improve this answer





















  • Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the %c%x pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something like isalpha or isdigit to test the first character of the line.
    – paddy
    Nov 12 at 3:05










  • You use the wrong format specifier , %x is for unsigned int
    – M.M
    Nov 12 at 3:29














0












0








0






In such cases, where you will be trying to parse the same line many times, it is better to read the line into memory, and then deal with the data in memory, rather than on disk.



char line[MAXLINE];
fgets(line, MAXLINE, iFile);


Then you have what I call the "sscanf ladder," which is a series of if-else if clauses, each of which attempts to parse line in different ways. The condition would examine the return value of sscanf, since the number of objects successfully read is the return value. So we use this number to distinguish among several different formats:



if (sscanf(line, "%c%x", &instr, &address) == 2)
/* you have an instruction and an address */
else if (sscanf(line, "%x", &address) == 1)
/* you have an address only */


Since, in your case, this is a loop condition, you will have to refactor this into a function of its own:



int readAtLeastAddress(const char *const line, char *instr, unsigned long long *address)
{
return sscanf(line, "%c%x", instr, address) == 2 || sscanf(line, "%x", &address) == 1;
}


Then you would rewrite the loop as such



while (readAtLeastAddress(line, &instr, &address)) {
printf("%c", instr);
}





share|improve this answer












In such cases, where you will be trying to parse the same line many times, it is better to read the line into memory, and then deal with the data in memory, rather than on disk.



char line[MAXLINE];
fgets(line, MAXLINE, iFile);


Then you have what I call the "sscanf ladder," which is a series of if-else if clauses, each of which attempts to parse line in different ways. The condition would examine the return value of sscanf, since the number of objects successfully read is the return value. So we use this number to distinguish among several different formats:



if (sscanf(line, "%c%x", &instr, &address) == 2)
/* you have an instruction and an address */
else if (sscanf(line, "%x", &address) == 1)
/* you have an address only */


Since, in your case, this is a loop condition, you will have to refactor this into a function of its own:



int readAtLeastAddress(const char *const line, char *instr, unsigned long long *address)
{
return sscanf(line, "%c%x", instr, address) == 2 || sscanf(line, "%x", &address) == 1;
}


Then you would rewrite the loop as such



while (readAtLeastAddress(line, &instr, &address)) {
printf("%c", instr);
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 12 at 2:20









stackptr

8,28023256




8,28023256












  • Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the %c%x pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something like isalpha or isdigit to test the first character of the line.
    – paddy
    Nov 12 at 3:05










  • You use the wrong format specifier , %x is for unsigned int
    – M.M
    Nov 12 at 3:29


















  • Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the %c%x pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something like isalpha or isdigit to test the first character of the line.
    – paddy
    Nov 12 at 3:05










  • You use the wrong format specifier , %x is for unsigned int
    – M.M
    Nov 12 at 3:29
















Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the %c%x pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something like isalpha or isdigit to test the first character of the line.
– paddy
Nov 12 at 3:05




Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the %c%x pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something like isalpha or isdigit to test the first character of the line.
– paddy
Nov 12 at 3:05












You use the wrong format specifier , %x is for unsigned int
– M.M
Nov 12 at 3:29




You use the wrong format specifier , %x is for unsigned int
– M.M
Nov 12 at 3:29


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53255077%2fusing-fscanf-with-a-while-loop-to-store-a-char-and-int%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Xamarin.form Move up view when keyboard appear

Post-Redirect-Get with Spring WebFlux and Thymeleaf

Anylogic : not able to use stopDelay()