C program to send 3 lines of text (to a printer) - c

I need to code a program that takes input from a given register (sending bytes) to a printer and the first sentence has to be the student name in uppercase which I tried with toupper() by converting the register to a given variable (char ch;), though the given result was not met.
The next one is for the faculty number (it says in "condensed" font? Not sure what that is supposed to mean, please correct me if I'm wrong but I take it as it's supposed to be all lowercase?)
Finally, the last given sentence should print the date on the screen as well but unfortunately it doesn't say whether it should take the system date or whatever. (I've done it using printf and written the current date)
Here is the code I've written so far:
(the toupper() function does not work)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <bios.h>
#include <string.h>
#include <ctype.h>
void main()
{
int i; char ch; char row[1000];
union REGS r;
clrscr();
memset(row,0,sizeof(row));
r.h.ah=0; // function 0h
int86(0x16,&r,&r);
for(i=0; i<1;i++)
{
ch = row[i];
printf("student name", toupper(ch));
ch = r.h.al;
r.h.ah=0;
int86(0x17,&r,&r);
r.x.dx=0;
printf("\n");
printf("16630960",row[i]);
row[i]=r.h.al;
r.h.ah=0;
int86(0x17,&r,&r);
r.x.dx=0;
printf("\n");
printf("10-04-2022",row[i]);
row[i]=r.h.al;
r.h.ah=0;
int86(0x17,&r,&r);
r.x.dx=0;
}
r.h.ah=0;
r.h.al=0x0A;
r.x.dx=0;
int86(0x17,&r,&r);
getch();
delay(100);
}

I am not sure what all that DOS interrupt thing is doing but I can at least fix the 'uppercase is broken' complaint
printf("student name", toupper(ch));
You are attempting to print one character of the name (thats probably not correct, but lets at least get that one character printed)
printf("student name %c", toupper(ch));
Now you need to fix all the other printfs
to convert whole string to upper case, assuming 'row' contains the string
int len = strlen(row);
for(int i = 0; i < len; i++){
row[i] = toupper(row[i]);
}

Related

Segmentation error while working with strings

Given a string, num, consisting of alphabets and digits, find the frequency of each digit(0-9) in the given string.
'''
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include<ctype.h>
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
char num[20];
int i;
int count[15]={0};
scanf("%s",num);
for(i=0;i<10;i++){
printf("\n");
for(int j=0;j<strlen(num);j++){
if(isdigit(num[j])){
if(i == num[j]-'0'){
count[i]+=1;
}
}
}
printf("\nCount %d:%d",i,count[i]);
}
for(i=0;i<10;i++){
printf("%d ",count[i]);
}
return 0;
}
'''
OUTPUT:
Count 0:5
Count 1:9
Count 2:5
Count 3:12
Count 4:8
Count 5:11
Count 6:15
Count 7:4
Count 8:4
exited, segmentation fault
Why is it not working when checking if the digit is 9?
When looking at your output, it seems that you have entered a string much longer than 19 characters. So your program has undefined behavior.
This
scanf("%s",num);
is something that you should never do. Remember to limit the input to the size of your buffer. That is:
char num[20]; // Size of buffer is 20
scanf("%19s",num);
^^
At max allow 19 characters so that there is also room for the string termination
Or - perhaps better - use fgets instead of scanf. One benefit of fgets is that it takes the buffer size as argument - consequently you never forget to specify it.
Also notice that your outer for loop is unnecessary. You can update the array directly using a single loop.
// for(i=0;i<10;i++){ Delete this - it's not needed
for(int j=0;j<strlen(num);j++)
{
if(isdigit(num[j]))
{
count[num[j]-'0']+=1; // Update array
}
}
BTW: You only need 10 elements in the counter, i.e.
int count[15]={0}; ---> int count[10]={0};

Not able to take string and float as input in a single line in C

What I have till now is this. I am not able to figure out how to take the input as mentioned and solve this problem?
#include<stdio.h>
#include <stdlib.h>
#include<float.h>
int main()
{
char s[50];
float mil,min=FLT_MAX;
while(scanf("%s#%f",s,&mil)!=-1)
{
printf("%s\n",s);
if(mil<min)
min=mil;
}
}
EDIT: My problem is that when I print the string s inside the loop, "Zantro#16.15" is printed whereas I want only "Zantro" to be stored in s and 16.15 to be stored in mil
%s scans up until a whitespace. Scan up until a # instead.
while (scanf("%[^#]#%f", s, &mil) == 2)
Remember to specify the maximum buffer size in the scanning format to protect against overflows:
while (scanf("%49[^#]#%f", s, &mil) == 2)
Well the scanf function can not easily determine, that you want the # sign to be a delimiter. Therefore you need to add an extra step to split up the strings into proper parts and store them for later comparison.
Have a look at strtok function in c.
http://www.c-howto.de/tutorial/strings-zeichenketten/string-funktionen/string-zerteilen/
Here is a solution that prints the requested string:
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <string.h>
int main()
{
char s[50];
char mins[50];
float mil,min=FLT_MAX;
int rc;
int done=0;
while (done == 0)
{
rc = scanf("%49[^#]#%f", s, &mil);
if (rc != 2)
{
done = 1;
continue;
}
if (mil < min)
{
min = mil;
strcpy(mins, s);
}
}
printf("%s\n", mins);
return 0;
}
Execution:
./sc
Zantro#16.15
Zirty#12.5
Gamry#9.8
Gamry
#include<stdio.h>
#include <stdlib.h>
#include<float.h>
int main()
{
char s[50];
float mil, min = FLT_MAX;
while (scanf("%[^#]#%f", s, &mil) == 2)
{
printf("%s\n", s);
if (mil < min)
min = mil;
}
}
Input:Zantro#16.15Zity#12.5Gamry#9.8
OutPut:
Zantro
Zity
Gamry
If you want to split your input in the scanf to string and float, you have to write those two types separately. For example, ("%s %f"). This string tells the function, what will be the arguments types. Therefore, if you write it like this ("%s#%f") the scanf function has a problem to understand, what will be the inputs types. In addition, if you write ("%s #%f") it will get two inputs like this " #". Your problem here is the space between the two arguments. Because, I didnt find how to get the input without this space. I'm recommending you to try splitting the input in another way.
For example, take one string that holds the intaier input to string buffer-> scanf("%s",sBuffer).
and split that to different variables after that.

Getting an infinite running program when using scanf

I'm getting an infinite running programm when I use the following code to read a string from keyboard and save it within a structured vector.
scanf("%s", strk_zgr_fp->bezeichnung, (int)sizeof(strk_zgr_fp->bezeichnung - 1));
Simply nothing happens after this line is reached and the program runs infinitly.
I know scanf() isn't recommended. We're using it only within our C beginners course and I want you to keep it in mind, ie please don't recommend other function rather than above mentioned for the moment.
Any help is much appreciated, thanks in advance.
#include <stdio.h>
typedef struct {
int nummer;
char bezeichnung;
int menge;
float preis;
} artikel;
void eingabe_artikel(artikel *strk_zgr_fp, int i_fp);
void ausgabe_artikel(artikel *strk_zgr_fp, int i_fp);
void main(void) {
artikel artikelliste[10];
artikel *strk_zgr;
int anzahl;
do {
printf("Bitte eine #Artikel eingeben [<= 10]: ");
scanf("%d", &anzahl);
if(anzahl < 1 || 10 < anzahl)
printf("\nEs wurde eine falsche #Artikel eingegeben.");
} while(anzahl < 1 || 10 < anzahl);
for(int i = 0; i < anzahl; i++)
eingabe_artikel(&artikelliste[i], i);
int i;
for(strk_zgr = artikelliste, i = 0; strk_zgr < artikelliste + anzahl;
strk_zgr++, i++)
ausgabe_artikel(strk_zgr, i);
}
void eingabe_artikel(artikel *strk_zgr_fp, int i_fp) {
printf("\nBitte den %d. Artikel eingeben: ", ++i_fp);
printf("\nNummer: ");
scanf("%d", &strk_zgr_fp->nummer);
printf("Bezeichnung: );
scanf("%s", strk_zgr_fp, (int)sizeof(strk_zgr_fp->bezeichnung - 1)); /* <-- */
printf("Menge: ");
scanf("%d", &strk_zgr_fp->menge);
float preis;
printf("Preis: );
scanf("%f", &preis);
strk_zgr_fp->preis = preis;
}
void ausgabe_artikel(artikel *strk_zgr_fp, int i_fp) {
printf("\n%d. Artikel: ", ++i_fp);
printf("\nNummer:\t%d", strk_zgr_fp->nummer);
printf("\nBezeichnung:\t%s", strk_zgr_fp->bezeichnung);
printf("\nMenge:\t%d", strk_zgr_fp->menge);
printf("\nPreis:\t%.2f EUR\n", strk_zgr_fp->preis);
}
NetBeans Version
Complier Version
Many problems in the code. Please at least fix the missing ending quotes on the printf() calls.
Now to the beef:
1) Your structure is wrong. 'Bezeichnung' is defined as a single character, not a string.
typedef struct {
int nummer;
char bezeichnung[100];
int menge;
float preis;
} artikel;
2) You cannot use scanf() in the way you did. If you want to limit the input length (which always is a good idea), you need to pass the maximum length into the format string.
Do you nee to use scanf()?? Because it gets messy from here on....
As your maximum input length might be variable or subject to change (see 1.), you need to build the format string for scanf. Something like this:
char format_str[15];
format_str[0] = '%';
//Dont use itoa(), it is not C standard.
sprintf(&format_str[1], "%d", (int)sizeof(strk_zgr_fp->bezeichnung) - 1);
strcat(format_str, "s");
scanf(format_str, strk_zgr_fp->bezeichnung);
Hope that gets you going.
PS: You need to include string.h for strcat().
I tried it out and it worked fine for me. Not sure on this sprintf() function. Could you please explain why I'm supposed to use it? By now, I used this code: char format_str[20]; format_str[0] = '%'; strcat(format_str, "s"); printf("Bezeichnung: "); scanf(format_str, strk_zgr_fp->bezeichnung);
While that works, you are missing out on limiting the length of the user's input. That is why I proposed using sprintf() to create a (sub)string containing the maximal allowable length of the user input, depending on how large your 'bezeichnung' is defined in the struct. Suppose 'bezeichnung' has a limit of 100 characters, you would want to limit the input to 99 (+1 for the zero-termination), so you want a scanf format string like this: "%99s".
chux has provided a much more compact version of my three lines, but I think, in the beginning, you will have it easier to just assemble such format strings piece by piece, at the same time learning how to a) change individual characters in a string, how to use sprintf() in a basic way, and how to concatenate strings with strcat().
There was another example which I did and the course leader provided a scanf() function like this to read a string: scanf("%s", &(strk_zgr_fp->bezeichnung));. I thought when I'm reading a string the address operator isn't used. The only difference is the address operator now is used and the element was put into brackets.
Now, I think this is bad practice. It works, but is superfluous. Consider this small code snippet:
#include <stdio.h>
#include <stdlib.h>
struct test{
int i;
char a_str[10];
};
int main()
{
struct test a_test;
printf("Normal array adress taking: %p\n", a_test.a_str);
printf("Using '&' to take adress of array: %p\n", &(a_test.a_str));
return 0;
}
Hope that helps.

Strange character appearing at start of string

I am taking different transistor data from a file. The program stores that in a structure. It then prompts for an input from the user. User enters 5 different values, eg 12 0.03 100 320 65 and then the program takes these values and compares it to the data from the file and sees if any transistors would be suitable for the parameters you have entered.
The program then prompts the user again, and this repeats until the letter q is entered, which ends the program.
The problem I'm having - and I've been trawling the internet for hours trying to find a solution but none of them have worked - is that any input after the first set isn't accepted. So it looks like this.
Please input: Voltage Current Power Frequency Gain
15 0.1 200 100 80
15 0.1 200 100 80
ALL RELEVANT TRANSISTORS
Please input: Voltage Current Power Frequency Gain
20 0.3 100 150 40
?1 2 3 4 5
The question mark is always a strange character. In the past few hours it has been a ? in a diamond, the letter P, and a small square with 0010 in it. Everything I have found on the internet says this should work. What am I missing?
Here's my input function
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define MAX 15
struct input{
int volt, power, freq, gain;
float amp;
};
struct input inputs[MAX_IN];
int CHK =1, number=0;
int input_function1()
{
const char check[3] = {'\0'};
int i;
const char inp[30] = {'\0'};
printf("Please input: Voltage Current Power Frequency Gain\n");
fgets(inp, 30, stdin);
puts(inp); //Prints out the string to see if the input has been correctly accepted
ungetc(inp, stdin);
sscanf(inp, "%s", &check);
if(check[0]!='q' && check[1]!='q' && check[2]!='q')
{
sscanf(inp, "%d %f %d %d %d", &inputs[number].volt, &inputs[number].amp,
&inputs[number].power, &inputs[number].freq, &inputs[number].gain);
}
}
Below is how I am calling the function. check_function is the function which checks the input transistor against the database.
while(CHK==1)
{
input_function1();
check_function();
++number;
}
You are declaring a const char array like this:
const char test[30] = {'\0'};
and that actually creates a string/array that is not editable and the terminating 0 that should mark the end of a string is the only character in this array. Also this zero is being set at the test[0].
Here's a little example which fixes some stuff of your current snippet:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <conio.h>
#define MAX 15
struct input {
int volt, power, freq, gain;
float amp;
};
struct input inputs[MAX];
int fill_input(int index) {
char check[4];
char inp[30];
printf("Please input: Voltage Current Power Frequency Gain\n");
fgets(inp, 30, stdin);
puts(inp);
sscanf(inp, "%s", &check);
if (strcmp(check, "qqq") == 0) {
return 0;
}
sscanf(inp, "%d %f %d %d %d", &inputs[index].volt, &inputs[index].amp,
&inputs[index].power, &inputs[index].freq, &inputs[index].gain);
return 1;
}
int main(int argc, char *argv[]) {
int index = 0;
while (1 && index < MAX) {
if (!fill_input(index)) break;
index++;
}
printf("End");
getch();
}
The goal of the above snippet is to help you to move on.
Few notes for you to consider though:
Try to avoid global variables as much as possible
The current provided version is far away from being optimal, think why is that and don't just copy paste other's code, try to figure out what a good function is all about. The most important lesson for you here should be how to code proper functions
The errors in your snippet are related to arguments not matching properly the datatypes, for instance, take a look to the fgets docs, you can see the first argument is char*, you were using const char*, datatypes should match
Try to refactor the function till is good one and learn as much as possible from each refactoring
Have fun coding! <--- most important one

zip file I am trying to take an input file and compress the letters.

The problem is that I don't know how to call a function. I just need to compress letters into the amount of the letter there is and the letter example. for example aaaaa= 5a
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
zip(zipp);
FILE *ifp;
int main(){
int i,trials, num=0;
char zipp[30000], read[30000];
ifp=fopen("zip.txt","r");
fscanf(ifp, "%d", &trials);
for(i=0; trials>0; trials--){
for(i=0; read[i]!="\n";i++){
fscanf(ifp,"%c", read[i]);
num++;
}
zip[30000]=zip(read[i]);
}
}
int zip(i,num){
for(i=0;num>0;i++){
num--;
}
}
You need to first make your code error free..lots of error in your code
zip[30000]=zip(read[i]); which is wrong your array name should be
zipp i think as per your declaration. Also why you assign value on
fix index 30000. I not getting you.
Also declared your function zip properly like int zip(int i,int num).
Most important thing is how you zip your latter. i don't see any logic here.look some link and try like Zip file using C program
And and for this, i think you revise it again because read[i]!="\n" is checked first then taking input to it.
for(i=0; read[i]!="\n";i++){
fscanf(ifp,"%c", read[i]);
num++;

Resources