I am having issues in C with a switch case
#include <stdio.h>
#include <strings.h>
void runprogram(void); // parses the input file
void display(int, int); // prints out the requested lines
void clearmemory(void); // clears the choice for input file
int traceflag = 0; //determines if the output should say everything
char memory[128]; //the file name for the input
void runprogram (void)
{
FILE *ifp; //file loaded
int total=0; //accumulator total
int temp3;
int a, b, c, d, numcnt, operand, opcode, CNNN;
char ch, ch2;
printf("Current File: %s\n",memory);
if(traceflag==0)
printf("Trace is off\n");
else
printf("Trace is on\n");
ifp = fopen(memory,"r"); //opens the file
char line [128];
char NNN[3];
char Cnnn[4];
char C[1];
a=0;
b=0;
c=0;
d=0;
numcnt=0;
while(fgets(line,sizeof line,ifp)!= NULL) // read a line from a file
{
while ((ch = line[b]) != '\0' )
{
if ( numcnt == 1 )
{
if (isdigit(ch))
{
ch2 = line [b + 1];
if ( isdigit( ch2 ))
{
for (a = 0; a < 4; a++ )
{
Cnnn [ a ] = ch;
b++;
ch = line [ b ];
}
for (a=0;a<4;a++)
{
if (a==0)
opcode=Cnnn[a];
else
NNN[a-1]=Cnnn[a];
}
numcnt++;
b=0;
a=0;
}
}
}
else if ( isdigit(ch))
{
ch2 = line [ b + 1 ];
if ( ch2 == ' ' )
numcnt++;
}
else
ch = line [ b ];
b++;
ch = line [ b ];
}
fgets( line, sizeof(line), ifp);
numcnt=0;
b=0;
d=0;
for (c = 0; c < 3; c++)
{
NNN [ c ] = Cnnn [ d + 1 ];
d++;
}
sscanf(NNN, "%d", &operand);
opcode=opcode/10;
b=0;
d=0;
/*if(traceflag==1)
{
printf("Full Line: %s\n",line); //print the file
printf("Opcode: %d\n", opcode);
}*/
printf("Opcode: %d Operand: %d\n", opcode, operand);
switch ( opcode )
{
case 0: //0 - Halt
printf("Run finished \n");
break;
case 1: //1 - Load: Copy memory nnn to accumulator
total=operand;
break;
case 2: //2 - Store: Copy accumulator to memory nnn
operand=total;
break;
case 3: //3 - Add memory nnn to accumulator
total=total+operand;
break;
case 4: //4 - Subtract memory nnn from accumulator
total=total-operand;
break;
case 5:
//int temp3; //temp to hold entered number
printf("Enter a number: ");
scanf(" %d",&temp3);
total=temp3;
break;
case 6:
printf("Accumulator: %d\n",total);
break;
case 7:
if(total==0)
opcode=operand/10;
break;
case 8: //8 ‐ Branch to nnn if the accumulator > 0
if(total>0)
opcode=operand/10;
break;
case 9: //9 – Branch to nnn
opcode=operand/10;
break;
default:
total=0;
break;
}
}
printf("Run finished \n");
fclose(ifp);
}`
The opcode is always an int, and it is the right int to run the switch.
yet for some reason it skips over the switch runs through all the lines and never outputs anything from within the switch case.
the file loaded is
0 Rd 5000
1 st n 2017
2 ld zero 1014
3 st sum 2016
4 L: ld n 1017
5 Add sum 3016
6 St sum 2016
7 Ld n 1017
8 Sub one 4015
9 St n 2017
10 Brgt L 8004
11 Ld sum 1016
12 Wr 6000
13 Stop 0000
14 Zero: 0 0000
15 One: 1 0001
16 Sum: 0 0000
17 N: 0 0000
Im not quite sure whats wrong with if and im not sure whats wrong i have tried many things and cant find anything online to help. Any input would be appreciated and if you cant compile and run the program i will give all the code. since the code is over 200 lines long i felt it would be inappropriate to post it all, yet if i must i will.
The problem is in the line opcode=Cnnn[a];
opcode is an int and Cnnn[a] is a char when you assign an int to a char it assigns the int value of the character according to the ASCII encoding. Example:
#include<stdio.h>
int main()
{
int a;
char b = '1';
a = b;
printf("%d", a);
return 0;
}
This prints out 49 because according to ascii the character '1' corresponds to 49
EDIT:
Im not sure if this is the "Correct" approach to solve your problem but since we notice that the int values we get are 48 more than the int value we want we can do opcode = (Cnnn[a] - 48);
Related
#include <stdio.h>
int main()
{
int number; // We make 1 int named number
scanf("%d",&number); // We give to number some number xd
while (number!=0)// We made a loop while if number isn't 0 do that
{
printf("text");// print text
scanf("%d",&number); // and get again a number.
// So everything works well beside inserting some char instead of int.
// So what is the problem wont scanf return 0 so we exit the program not
// just printing a text all day? That's my first question.
}
return 0;
}
The second problem is how to make a program reading numbers from keyboard till I enter some special sign for ex '.' Yea we do it with loop while right? But how when scanf("%d",&something) it give me back 0 if I enter everything but number?
change it from scanf int to char
Assumption: You are reading a single char at a time
#include <stdio.h>
int main()
{
char c = "0";
int n = 0;
while (n != 46)// we made a loop while if char isn't '.' ASCII - 46 do that
{
scanf(" %c", &c);
n = (int)c;
printf("text %d", n);
//Add if statement to confirm it is a number ASCII 48 - 57 and use it.
}
return 0;
}
EDIT:
Just some more info on how to use numbers:
input number one by one or just a whole number like 123 with some ending special char like ';' or change the line
scanf(" %c", &c);
to:
scanf("%c", &c);
this way it will register '\n' as ASCII 10
use that with atoi to get the actual int value and use it.
EDIT 2:
#World, you cannot expect to read only numbers and '.'
One way to do this with your own code is:
#include <stdio.h>
int main()
{
char c = "0";
int n = 0;
int number = 0;
while (n != 46)// we made a loop while if char isn't '.' ASCII - 46 do that
{
scanf("%c", &c);
n = (int)c;
if (n>=48 && n<=57) {
number *= 10;
number += (n-48);
}
if (n==10) {
printf("text %d\n", number);
//Use number for something over here
number = 0;
}
}
return 0;
}
EDIT 3:
Logic behind this:
Let's say you enter 341 in the console
the line
scanf("%c", &c);
will read this one by one thus reading '3', '4', '1' and '\n' respectively
the while loop
while (n != 46)
will thus run 4 times where:
1st time
c = '3';
n = 51;
if (n>=48 && n<=57) is true;
number = 0 * 10;
number = number + n - 48 = 0 + 51 - 48 = 3
2nd time
c = '4';
n = 52;
if (n>=48 && n<=57) is true;
number = 3 * 10 = 30;
number = number + n - 48 = 30 + 52 - 48 = 34
3rd time
c = '1';
n = 49;
if (n>=48 && n<=57) is true;
number = 34 * 10 = 340;
number = number + n - 48 = 340 + 49 - 48 = 341
4th time
c = '\n';
n = 10;
if (n>=48 && n<=57) is false;
if (n==10) is true;
it prints "text 341" and sets number to 0
while loop exits when c = '.' and n = 46
how to make a program reading numbers from keyboard till I enter some special sign for ex '.'
When scanf("%d",&number) returns 0, there is some non-numeric input. Read that non-numeric input with alternate code.
#include <stdio.h>
int main() {
while (1) {
int number;
int scan_count = scanf("%d", &number);
if (scan_count == EOF) break; // End-of-file or rare input error.
if (scan_count != 1) {
int ch = fgetc(stdin);
if (ch == '.') break; // Expected non-numeric input to break the loop.
printf("Unexpected input character '%c'\n", ch);
} else {
printf("Expected numeric input: %d\n", ch);
}
} // endwhile
printf("Done\n");
}
A better approach is to ditch scanf() and use fgets()` to read user input. Then process the inputted string.
I was solving a question this is my code its working perfect on my local Work space with the below input and gives the expected output but in hacker rank it is a time out for compilation .
The problem statement is
In the given string:
occurs two times.
and occur one time each.
The remaining digits and don't occur at all.
Sample Input 1: lw4n88j12n1
Sample Output 1 : 0 2 1 0 1 0 0 0 2 0
Facing Issue with below input
Input:
9139f793308o0lo66h6vc13lgc697h0f6c32lu84445972k0o0l033od17c083yn5051d6j319hyo8j939n28d913015ns6zx5653x01211x12ch2526o65sg7xw6302141q9203s22l336319ll9yx4b597mr318a7943906750j4u152067nq83ne9f24thu96yd05173l47c803roxci45615f0w53i1sz913jj6za733l73tw6r66mq6p44sfhjr26h8e801z8zlcx2l1e65r2879xj3w3acv216196uq158o663y7oz2i5378v0v5w17762451t424352m23026r9o202i9785382o159e4gu1c8561157z5f1vqs5755465b8u728u956434mv944885li456628a994u7j5278m269n1pk8e46940q834h06il6h447888tr7ig72z10fe09k5g98h9bgt6z40v42s16pt6k3l3v45i83i01b9448g554741w766f2q7v31i085488h060e710p53076c6nm98pi946g8j2n6j8x29qa1ad48172y0u4818121p686bud89741201p54087u56g8scerv9pvhuo09re477zfb224i2c1325bj58jx4bk7b009f6446j5i95474p266i503r670n631x6940gwl71ejbx47imx576129248901765rnpu6l80084t0j1839f5y3409w2n403fu6ogw1170jmb6o5l520vg0703e0
Expected Output: 53 54 47 48 54 52 63 46 49 46
Thanks for the help in advance.
int main() {
int i;
int value;
char x;
int arr[10] = {0};
char * ptr =(char *)malloc(sizeof(char *));
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
scanf("%s",ptr);
while(*ptr != '\0')
{
if(*ptr >= 65 && *ptr <=90 || *ptr >=97 && *ptr <=122){
*ptr++;
}
else{
x = *ptr;
value = atoi(&x);
switch (value)
{
case 0:
arr[0]++;
*ptr++;
break;
case 1:
arr[1]++;
*ptr++;
break;
case 2:
arr[2]++;
*ptr++;
break;
case 3:
arr[3]++;
*ptr++;
break;
case 4:
arr[4]++;
*ptr++;
break;
case 5:
arr[5]++;
*ptr++;
break;
case 6:
arr[6]++;
*ptr++;
break;
case 7:
arr[7]++;
*ptr++;
break;
case 8:
arr[8]++;
*ptr++;
break;
case 9:
arr[9]++;
*ptr++;
break;
}
}
}
for(i=0;i<=9;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
Here is error: char * ptr =(char *)malloc(sizeof(char *));
sizeof(char *) Equal 4 or 8. You allocated memory for example 8 chars. When you write entire STDIN to ptr then you will overwrite memory on heap.
When you read from stdin you MUST specify max length example:
char str[256] = {'\0'}
scanf ("%255s",str); //Read max 255 chars
About your body of loop, this is better :)
uint8_t digit;
if (*ptr >= '0' && *ptr <= '9')
{
digit = (uint8_t)(*ptr - '0');
if (digit < 10)
{
arr[digit]++;
}
}
ptr++; //THERE IS NO STAR *
But you should use simple for with know length and
if (ptr[i] == '\0') break;
Hope it's helps.
Edit:
sizeof(char*) is 4 or 8 as suggested #dbush.
I want to read the contents of a text file and copy it to 3 arrays. The first 14 lines to 'a' array, next 14 to 'b' array and remaining to c. When I press one to enter the choice, it must display the first 14 lines of the .txt file. When I compile this code which I have given, it gives only the first character to the whole array. Please help and thanks in advance.
My code:
#include<stdio.h>
#include<string.h>
void main()
{
int x,i;
char *a[100],*b[100],*c[100];
FILE *stream,*out;
char ch;
clrscr();
stream=fopen("test.txt","r");
while((ch=fgetc(stream))!=EOF)
{
for(i=0;i<14;i++)
a[i]==ch;
//ch=fgetc(stream);
//printf("%c",ch);
}
fclose(stream);
printf("Enter your choice");
scanf("%d",&x);
switch(x)
{
case 1:
for(i=0;i<14;i++)
printf("%s\n",a[i]);
break;
case 2:
for(i=0;i<14;i++)
printf("%s\n",b[i]);
break;
case 3:
for(i=0;i<14;i++)
printf("%s\n",c[i]);
break;
case 4:
exit(0);
default:
printf("Invalid choice");
break;
}
getch();
}
Current Output:
Enter your choice1
n
n
n
n
n
n
n
n
n
n
n
n
typedef char *CP14[14];
int main(){
int x,i;
char *a[14], *b[14], *c[14];
CP14 *abcp, *p[] = {&a, &b, &c, NULL};
char buffer[14*3*128]={0};//128 : max of one line
FILE *stream;
int ch, nlcount=0;//ch is int for fgetc
int gp = 0;
stream=fopen("test.txt","r");
abcp = p[gp];
(*abcp)[0]=&buffer[0];
for(i=0;i<sizeof(buffer)-1 && (ch=fgetc(stream))!=EOF;++i){
if('\n'== (buffer[i] = ch)){
buffer[i]= '\0';
if(++nlcount == 14){
nlcount = 0;
if(NULL == (abcp = p[++gp]))
break;
}
(*abcp)[nlcount]=&buffer[i+1];
}
}
fclose(stream);
...
You do not need the while loop if you know that the file is going to have 14*3 characters.
Simply read them in three consecutive for loops. Something like:
for(i=0;i<14;++i)
a[i]=fgetc(stream));
for(i=0;i<14;++i)
b[i]=fgetc(stream));
for(i=0;i<14;++i)
c[i]=fgetc(stream));
Also, == is a comparison and not assignment operator.
I have declared an array char Buffer[100]="01 05 01 4A 63 41"; now the array looks like this
Buffer[0]='0'
Buffer[1]='1'
Buffer[2]=' '
Buffer[3]='0'
Buffer[4]='5'
i just want to convert these value to int `eg.:
Buffer[0]='0', Buffer[1]='1' to 0x01 (1)
Buffer[0]='0', Buffer[1]='5' to 0x05 (5)
... etc.
atoi()cannot be used since it converts all the Buffer value as integer.
How to convert a particular space delimited value sub-string to an integer?
My first solution works only for integers, and the following one works also for hexadecimal numbers. I wrote down the function which converts string representation of a hexadec. number into a decimal number. Then, as suggested by Jochim Pileborg, I used strtok to parse the given Buffer array.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int hexToInt(char *tok)
{
int i,out=0, tens=1, digit;
for(i=strlen(tok)-1; i>=0; i--)
{
switch(tok[i])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': digit=tok[i]-'0';
break;
case 'A': digit=10; break;
case 'B': digit=11; break;
case 'C': digit=12; break;
case 'D': digit=13; break;
case 'E': digit=14; break;
case 'F': digit=15; break;
}
out+=digit*tens;
tens*=16;
}
// printf("hex:%s int:%d ", tok, out);
return out;
}
int main()
{
char Buffer[100]="01 2A 10 15 20 25";
int intarr[100],current=0;
char *tok=malloc(20*sizeof(char));
tok=strtok(Buffer," ");
while(tok!=NULL)
{
intarr[current]=hexToInt(tok);
current++;
tok=strtok(NULL," ");
}
printf("\n");
}
You can treat Buffer as a string (which it is), and use e.g. strtok to "tokenize" the numbers on space boundary. Then use strtol to convert each "token" to a number.
But do note that strtok modifies the string, so if you don't want that you have to make a copy of the original Buffer and work on that copy.
Also note that as the numbers seems to be hexadecimal you can't use atoi because that function only parses decimal numbers. You have to use strtol which can handle any base from 2 to 36.
Consider this:
#include <stdio.h>
int main()
{
char Buffer[100] = "01 05 01 4A 63 41" ;
const char* h = &Buffer[0] ;
int i ;
while( *h != 0 )
{
if( sscanf( h, "%2x", &i ) == 1 )
{
printf( "0x%02X (%d)\n", i, i ) ;
}
h += 3 ;
}
return 0;
}
The output from which is:
0x01 (1)
0x05 (5)
0x01 (1)
0x4A (74)
0x63 (99)
0x41 (65)
I have assumed that all the values are hexadecimal, all two digits, and all separated by a single space (or rather a single non-hex-difgit character), and that the array is nul terminated. If either of these conditions are not true, the code will need modification. For example if the values may be variable length, then the format specifiers need changing, and, you should increment h until a space or nul is found, and if a space is found, increment once more.
You could write similar code using strtol() instead of sscanf() for conversion, but atoi() is specific to decimal strings, so could not be used.
If you are uncomfortable with the pointer arithmetic, then by array indexing the equivalent is:
#include <stdio.h>
int main()
{
char Buffer[100] = "01 05 01 4A 63 41" ;
int c = 0 ;
int i ;
while( *h != 0 )
{
if( sscanf( &Buffer[c], "%2x", &i ) == 1 )
{
printf( "0x%02X (%d)\n", i, i ) ;
}
c += 3 ;
}
return 0;
}
and the strtol() version if you prefer:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char Buffer[100] = "01 05 01 4A 63 41" ;
const char* h = &Buffer[0] ;
while( *h != 0 )
{
int i = strtol( h, 0, 16 ) ;
printf( "0x%02X (%d)\n", i, i ) ;
h += 3 ;
}
return 0;
}
You can use sscanf for this, e.g.:
int intarr[6];
sscanf(Buffer,"%d %d %d %d %d %d",&intarr[0],&intarr[1],&intarr[2],&intarr[3],&intarr[4],&intarr[5]);
You can cast Buffer[i] to int.
Then check its value, which will be in ASCII.
48->0
.
.
57->9
You can even compare the char to its ASCII value without casting
int CharToDigit(char c)
{
if(c>=48 && c<=57) // or as suggested if(c>='0' && c <='9')
return (int)c - 48; // subtract the ascii of 0
return -1; // not digit
}
For digits from A to F you'll have to subtract 55 from uppercase letters (65-10, 65 is ascii of A)
Then loop through the chars in Buffer sending them to the function: CharToDigit(Buffer[i]) and check the returned int.
I'm trying to get ints from a c file that has input like this:
(0 3 200 3) (0 9 500 3) (98 20 500 3) (100 1 100 3) (100 100 500 3)
atoi and s work fine for the first number after the parenthesis (I use a while loop and strcat numbers larger than one digit) and any number that is only one digit, but they only return the first digit for numbers that are not right after the parenthesis.
Here is what the code for the method:
void allProcesses(FILE file, struct process processArray[]) {
char ch;
int number;
int a, b, c, io;
int arrayCount = 0;
int processIndex = 0;
char temp[1];
while ((ch = fgetc(&file)) != EOF) {
if (isdigit(ch)) {
char numberAppended[20] = "";
while (isdigit(ch)) {
temp[0] = ch;
strcat(numberAppended, temp);
ch = fgetc(&file);
}
char* end;
number = (int)strtol(numberAppended, &end, 0);
printf("The number is %d\n",number);
int atoinum = atoi(numberAppended);
switch (processIndex) {
case 0:
a = number;
if (DEBUG == TRUE) {
printf("a = %c\n", a);
printf("NUmber a is %d\n", a);
}
processIndex++;
break;
case 1:
b = number;
if (DEBUG == TRUE) {
printf("b = %c\n", b);
printf("NUmber b is %d\n", b);
}
processIndex++;
break;
case 2:
c = number;
if (DEBUG == TRUE) {
printf("c = %c\n", c);
printf("NUmber c is %d\n", c);
}
processIndex++;
break;
case 3:
io = number;
if (DEBUG == TRUE) {
printf("io = %c\n", io);
printf("NUmber io is %d\n", io);
}
processIndex++;
break;
default:
break;
}
}
if (ch == ')') {
processArray[arrayCount] = makeProcess(a, b, c, io);
arrayCount++;
processIndex = 0;
}
}
}
First (read comments):
you have declared char temp[1]; one size it has to be of size 2 according to your code(otherwise undefined behavior because memory overrun):
char temp[2];
while (isdigit(ch)) { // from `(` to `)`
temp[0] = ch; // should be a null terminated
temp[1] = '\0'; // add this step;
strcat(numberAppended, temp);
ch = fgetc(&file);
}
Second: your numberAppended is parse to a string of kind: "0 9 500 3"
and your are calling
number = (int)strtol(numberAppended, &end, 0);
^
output argument
syntax for strtol:
long int strtol(const char *numberAppended, char **end, int base);
Where
numberAppended: is the string to be converted into a long integer.
end: points to a pointer that will be set to the character immediately following the long integer in the string "numberAppended".
And your are to write something like this: (read comments)
end = numberAppended; // assign to first string
// in a loop {
number = (int)strtol(end, &end, 0); // in loop end is input &end is output
printf("The number is %d\n",number);
//}
My following code will help your to understand how to use strtol() to parse and extract number from numberAppended string:
#include <stdio.h> /* printf */
#include <stdlib.h> /* strtol */
int main (){
char numberAppended[] = "2001 11 223 444 566";
char * end;
long int li;
end =numberAppended;
int base =10;
int ele = 0;
while(li=strtol (end, &end, base)){
printf("%ld \n", li);
ele += 1;
}
printf("\nNo of elements: %d", ele);
return 0;
}
output:
2001
11
223
444
566
No of elements: 5
third: may be its not an error but I couldn't find where processIndex updates in your code before switch(){}..