could somebody help me with this? I'm beginner in C programming and I don't know how I can print the strings from table from stdin and how can I count how many strings are there...
for example './program select row 3 < tab.txt but I have no idea how to do it...
int i;
char c(stidn);
int i, *p_i;
p_i = &i;
int select() {
while ((c=getchar()) != EOF)
{
i++;
}
}
int row(){
if (i == (argc 4))
printf("%s\n", p_i);
}
then I will call select and then row in main()
if ((argc == 4) && (strcmp("select", argv[1]) == 0)){
if (argc 4 == p_i)
{
row;
}
I know this is wrong but as I sad...I have no idea what I can do :|
First we need to get the right row. We will do this be counting all the newlines we detect when reading the input.
unsigned int GoToRow(unsigned int row) //First row has index zero
{
unsigned int nlCount = 0;
int c = 0;
while(nlCount < row && c != EOF)
{
c = getchar();
if(c == '\n')
{
nlCount++;
}
}
return nlCount;
}
The next thing we need to do, is to get the row from the input.
void GetRow(char* pString, int maxchars)
{
int charCount = 0;
while((charCount + 1 < maxchars) || pString[charCount - 1] == '\n')
{
pString[charCount] = getchar();
charCount++;
}
pString[charCount] = '\0';
}
The main function of our program
int main(int argc, char** argv)
{
unsigned int rownumber = 3;
char rowdata[500];
if(argc == 4 && (strcmp(argv[1], "select") == 0) && (strcmp(argv[2], "row") == 0))
{
rownumber = atoi(argv[3]);
}
int rowscounted = GoToRow(rownumber);
GetRow(rowdata, 500);
rowscounted++;
rowscounted += GoToRow((unsigned int)-1); //Go to the end of the data
printf("Number of rows : %d\n Selected row : %s", rowscounted, rowdata);
return 0;
}
Related
I tried to make calculator supporting brackets, but
I have no idea how to deal if the user's input includes expression with spaces, for example:
input: (2 + 3) * 2
i got: 2
If it's normally get (2+3)*2, it counts 10
.
My code:
#include <stdio.h>
#define MAX_SIZE 1024
int insert_operand(int *operand, int * top_num, int num) /* data is pushed into the data stack*/
{
(*top_num) ++;
operand[*top_num] = num; /*save data*/
return 0; /*Exit normally*/
}
int insert_oper (char * oper , int *top_oper , char ch)
{
(*top_oper)++;
oper[*top_oper] = ch; /*save operator*/
return 0; /*Exit normally*/
}
int compare(char *oper , int *top_oper , char ch) /* compare the priority of the operating server*/
{
if((oper[*top_oper] == '-' || oper[*top_oper] == '+') /*Determine whether the current priority is higher than the priority of the operator at the top of the stack*/
&& (ch == '*' || ch == '/'))
{
return 0;
}
else if(*top_oper == -1 || ch == '('
|| (oper[*top_oper] == '(' && ch != ')')) /*Determine whether the operator stack is empty; whether the top operator is '('*/
{
return 0;
}
else if (oper[*top_oper] =='(' && ch == ')')
{
(*top_oper)--;
return 1;
}
else
{
return -1; /*Operate the operator*/
}
}
int deal_date(int *operand ,char *oper ,int *top_num, int *top_oper) /*perform data operation*/
{
int num_1 = operand[*top_num]; /*Take out two data from the data stack*/
int num_2 = operand[*top_num - 1];
int value = 0;
if(oper[*top_oper] == '+')
{
value = num_1 + num_2;
}
else if(oper[*top_oper] == '-')
{
value = num_2 - num_1;
}
else if(oper[*top_oper] == '*')
{
value = num_2 * num_1;
}
else if(oper[*top_oper] == '/')
{
value = num_2 / num_1;
}
(*top_num) --; /*Move the top of the data stack down one bit*/
operand[*top_num] = value; /*Push the obtained value into the data stack*/
(*top_oper) --; /*Move the top of the operator stack down one bit*/
}
int main()
{
int operand[MAX_SIZE] = {0}; /*data stack, initialize*/
int top_num = -1;
char oper[MAX_SIZE] = {0}; /*operator stack, initialize*/
int top_oper = -1;
char *str = (char *) malloc (sizeof(char) * 100); /*get expression (without =)*/
scanf("%s", str);
char* temp;
char dest[MAX_SIZE];
int num = 0;
int i = 0;
while(*str != '\0')
{
temp = dest;
while(*str >= '0' && *str <= '9') /*judging whether it is data*/
{
*temp = *str;
str++;
temp++;
} /*Encounter a symbol to exit*/
if(*str != '(' && *(temp - 1) != '\0') /*Determine whether the symbol is '('*/
{
*temp = '\0';
num = atoi(dest); /*convert string to number*/
insert_operand(operand, &top_num,num); /*Push data into the data stack*/
}
while(1)
{
i = compare(oper,&top_oper,*str); /*judgment operator priority*/
if(i == 0)
{
insert_oper(oper,&top_oper,*str); /*press operator*/
break;
}
else if(i == 1) /*judging whether the expression in brackets ends*/
{
str++;
}
else if(i == -1) /* data processing */
{
deal_date(operand,oper,&top_num,&top_oper);
}
}
`
str ++; /* point to the next character of the expression */
}
`
printf("%d\n",operand[0]); /*output result*/
return 0;
I tried to count the equation even if there is a space in it. Can someone please help?
Solving the problem by removing spaces:
So if you're working with equation as string you can simply remove spaces with function like this (there will be probably better way or function in library string.h but this was first guess):
char* DeleteSpaces( char* stringWithSpaces, size_t lengthOfString)
{
char* stringWithoutSpaces = (char*)calloc(lengthOfString + 1, sizeof(char));
if( !stringWithoutSpaces )
return NULL;
for( unsigned int x = 0, y = 0; x <= lengthOfString; x++, y++ )
{
if( stringWithSpaces[x] == ' ' ) // if the character is space
{
while( stringWithSpaces[x] == ' ' && x < lengthOfString ) // skip all the spaces OR go away before you hit '\0'
x++;
stringWithoutSpaces[y] = stringWithSpaces[x]; // then copy next character into new string
}
else // if there's no space just copy the character
stringWithoutSpaces[y] = stringWithSpaces[x];
}
return stringWithoutSpaces;
}
This will basically remove all spaces from your received equation. If you really need the smallest possible memory requirement you can use realloc() at the end of the function for more optimal memory usage.
Here's simple example of how to use the function so you can test it:
int main()
{
char firstString[] = "H e l l o w o r l d\0";
char* secondString;
secondString = DeleteSpaces( firstString, strlen(firstString) );
if( !secondString )
return -1;
printf( "%s", secondString );
free( secondString );
return 0;
}
Don't forget to use free(SecondString). I hope I helped you atleast a little :)
As with the previous answer, I added in a function to remove any spaces from the entered formula in order to process the requested calculation. Also, coupled with that, I revised the "scanf" input to read in all of the entered characters which looked to be another symptom you were facing. With that, following is a refactored version of your program with the additional space compression function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 1024
int insert_operand(int *operand, int * top_num, int num) /* data is pushed into the data stack*/
{
(*top_num) ++;
operand[*top_num] = num; /*save data*/
return 0; /*Exit normally*/
}
int insert_oper (char * oper , int *top_oper , char ch)
{
(*top_oper)++;
oper[*top_oper] = ch; /*save operator*/
return 0; /*Exit normally*/
}
int compare(char *oper , int *top_oper , char ch) /* compare the priority of the operating server*/
{
if((oper[*top_oper] == '-' || oper[*top_oper] == '+') /*Determine whether the current priority is higher than the priority of the operator at the top of the stack*/
&& (ch == '*' || ch == '/'))
{
return 0;
}
else if(*top_oper == -1 || ch == '('
|| (oper[*top_oper] == '(' && ch != ')')) /*Determine whether the operator stack is empty; whether the top operator is '('*/
{
return 0;
}
else if (oper[*top_oper] =='(' && ch == ')')
{
(*top_oper)--;
return 1;
}
else
{
return -1; /*Operate the operator*/
}
}
int deal_date(int *operand ,char *oper ,int *top_num, int *top_oper) /*perform data operation*/
{
int num_1 = operand[*top_num]; /*Take out two data from the data stack*/
int num_2 = operand[*top_num - 1];
int value = 0;
if(oper[*top_oper] == '+')
{
value = num_1 + num_2;
}
else if(oper[*top_oper] == '-')
{
value = num_2 - num_1;
}
else if(oper[*top_oper] == '*')
{
value = num_2 * num_1;
}
else if(oper[*top_oper] == '/')
{
value = num_2 / num_1;
}
(*top_num) --; /*Move the top of the data stack down one bit*/
operand[*top_num] = value; /*Push the obtained value into the data stack*/
(*top_oper) --; /*Move the top of the operator stack down one bit*/
return value;
}
void compress(char *stx) /* The additional function */
{
char work[101];
int i = strlen(stx);
strcpy(work, stx);
for (int j = 0; j < i; j++)
{
stx[j] = 0;
}
i = 0;
for (int j = 0; j < (int)strlen(work); j++)
{
if (work[j] != ' ')
{
stx[i] = work[j];
i++;
}
}
}
int main()
{
int operand[MAX_SIZE] = {0}; /*data stack, initialize*/
int top_num = -1;
char oper[MAX_SIZE] = {0}; /*operator stack, initialize*/
int top_oper = -1;
char *str = (char *) malloc (sizeof(char) * 100); /*get expression (without =)*/
//scanf("%s", str);
scanf("%[^\n]", str); /* Refined the scanf call to receive all characters prior to the newline/return character */
compress(str); /* Added this function to remove spaces */
char* temp;
char dest[MAX_SIZE];
int num = 0;
int i = 0;
while(*str != '\0')
{
temp = dest;
while(*str >= '0' && *str <= '9') /*judging whether it is data*/
{
*temp = *str;
str++;
temp++;
} /*Encounter a symbol to exit*/
if(*str != '(' && *(temp - 1) != '\0') /*Determine whether the symbol is '('*/
{
*temp = '\0';
num = atoi(dest); /*convert string to number*/
insert_operand(operand, &top_num,num); /*Push data into the data stack*/
}
while(1)
{
i = compare(oper,&top_oper,*str); /*judgment operator priority*/
if(i == 0)
{
insert_oper(oper,&top_oper,*str); /*press operator*/
break;
}
else if(i == 1) /*judging whether the expression in brackets ends*/
{
str++;
}
else if(i == -1) /* data processing */
{
deal_date(operand,oper,&top_num,&top_oper);
}
}
str ++; /* point to the next character of the expression */
}
printf("%d\n",operand[0]); /*output result*/
return 0;
}
Testing out your sample formula with some additional spacing to ensure the compression function was working properly, following was the terminal output.
#Vera:~/C_Programs/Console/Calculate/bin/Release$ ./Calculate
(2 + 3) * 2
10
Give that a try and see if it meets the spirit of your project.
As pointed out in the comments and other answers, the solution may be to simply "compact" the spaces out of the string before trying to analyse the string's content.
This doesn't require a lot of code:
#include <stdio.h>
char *stripSP( char *src ) {
for( char *d = src, *s = src; ( *d = *s ) != '\0'; s++ )
d += *d != ' ';
return src;
}
int main( void ) {
char *s[] = { "Hello", "H e l l ooo", "(2 + 5) * 3" };
for( int i = 0; i < 3; i++ ) {
printf( "From '%s' ", s[i] );
printf( "'%s'\n", stripSP( s[i] ) );
}
return 0;
}
From 'Hello' 'Hello'
From 'H e l l ooo' 'Hellooo'
From '(2 + 5) * 3' '(2+5)*3'
Even more compact would be to use array indexing:
char *stripSP( char s[] ) {
for( int f=0, t=0; (s[t] = s[f++]) != '\0'; t += s[t] != ' ' ) {}
return s;
}
Snapshot
Introduction
Usual search engines receive a set of keywords and look for all the
documents that contain these keywords. The documents are listed in the
order of document significance. In this problem we consider the
significance of a document for a set of keywords is given by the
minimum number of words of the continuous piece of text that contains
all the searched keywords. For instance: consider the keywords “2008”
and “IEEEXtreme”, and the following two texts: “The registration for
the 2008 edition of IEEEXtreme is now open” and “IEEEXtreme 2008
edition is going to take place on March 8th 2008”. The significance of
the first text is 4, and of the second one is 2. If any of the given
words is not present in the text, the significance is zero.
Task
Please write a program that reads from the standard input a text in
which the words are separated only by spaces, and finds the
significance of text against the keywords given as the parameters to
your program.
Syntax
For the input text:
The registration for the 2008 edition of IEEEXtreme is now open
your program executed as:
> snapshot 2008 IEEEXtreme
should write 4 on the standard output. Note: if not all
the words are found, the program should return 0.
#include <stdio.h>
#include <string.h>
int compare(char *x, char *z) {
int a = 0;
if (strlen(x) == strlen(z)) {
while (a < strlen(x)) {
if (x[a] == z[a])
a++;
else
return 0;
}
return 1;
}
}
int verify(int q, int n, char *v) {
static int flag2 = 0;
static int error = 0;
if ((v[0] == '#') && (v[1] == '#') && (v[2] == '#') && (v[3] == '#')
&& (v[4] == '#')) {
flag2 = 1;
} else {
error++;
}
if ((q = n - 1) && flag2 == 1 && error == 0)
return 1;
else
return 0;
}
int main(int argc, char *argv[]) {
char text[1000];
char word[30];
FILE *fp = fopen("filename", "r");
int i = 0, j = 0, k = 0, y = 1, w = 1, t = 1, flag = 0, signifiancia = 0,
sucesso = 0;
while (feof(fp))
text[i++] = fgetc(fp);
text[i] = '\0';
while (text[j] != '\0') {
if (text[j] == ' ') {
j++;
word[k] = '\0';
k = 0;
while (y < argc) {
compare(argv[y], word);
if (1) {
flag = 1;
argv[y] = "#####";
signifiancia++;
y++;
} else {
if (flag = 1)
signifiancia++;
y++;
}
}
} else {
word[k] = text[j];
j++;
k++;
}
while (w < argc) {
verify(t, argc, argv[w]);
t++;
if (1) {
sucesso++;
printf("%d", signifiancia);
}
}
}
if (sucesso == 0)
printf("0");
}
The error given is:
Segmentation fault (core dumped)
At least these problems:
Missing return
When if (strlen(x) == strlen(z)) is false, function does not return anything.
Yet calling code does not use the return value anyways.
Assignment rather than compare
if (flag = 1)
Too many loops
Code iterates once too often.
while (feof(fp))
text[i++] = fgetc(fp);
Infinite loop
Once while (w < argc) { loop is entered, it appears to iterate infinitely - likely leading to UB.
Failure to prevent buffer over-runs
Compiles without warnings or errors, just the following code crashes when I try to either read from or write to the matrix constValues.
It needs to be passed to another function to be read from also; the function createOutputLine.
How can I point to the data held correctly so it can be modified and read from? Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
void createOutputFile(FILE*, int, char**);
char createOutputLine(int, int, char*, char**);
int main(int argc, char **argv) {
int removeComments = 0;
FILE *file;
if (argc > 1 && strcmp(argv[1], "-i") == 0) {
if (argc > 2) {
if (!(file = fopen(argv[2], "r"))) {
printf("Error: file not found");
return -1;
}
}
else {
printf("Error: no file specified");
return -1;
}
}
else {
printf("Error: command requires -i");
return -2;
}
createOutputFile(file, argc, argv);
fclose(file);
}
void createOutputFile(FILE *file, int argc, char **argv) {
fseek(file, 0, SEEK_SET);
char *data = (char*)malloc(2000);
FILE *header;
char name[20];
char *token = strtok(argv[2], ".");
strcpy(name, strcat(token, ".o"));
FILE *output = fopen(name, "w");
char constNames[10][15];
char **constValues[10][10];
int constsStored = 0;
while (fgets(data, 2000, file) != NULL) {
for (int i = 0; i < strlen(data); i++) {
int c = i;
bool linePrinted = false;
if (data[i] == '#' && data[i + 1] == 'd') {
for (c = i; c <= i + 7; c++) {
data[c] = '\0';
} int ch = 0;
while (data[c] != ' ') {
constNames[constsStored][ch] = data[c];
data[c] = '\0';
ch++;
c++;
} ch = 0;
while (data[c] != '\n') {
**constValues[constsStored][ch] = data[c]; //this line crashes
data[c] = '\0';
ch++;
c++;
}
if (data[c] == '\n') data[c] = '\0';
constsStored++;
}
for (int ch = 0; ch <= constsStored; ch++) {
if (data[i] == constNames[ch][0]) {
int ch2 = i + 1;
int ch3 = 1;
bool isConst = false;
while (data[ch2] != ' ') {
if (data[ch2] == constNames[ch][ch3] && isConst == false) isConst = true;
ch2++;
ch3++;
}
if (isConst || data[i + 1] == ' ') {
char line[200];
line[200] = createOutputLine(i, ch, data, **constValues);
fprintf(output, "%c", line[200]);
linePrinted = true;
}
}
}
if (!linePrinted)
fprintf(output, "%c", data[i]);
}
}
fclose(output);
free(data);
}
char createOutputLine(int i, int constElem, char *data, char **constValues) {
int ch = i;
int ch2 = 0;
char temp[200];
while (data[ch] != '\n' && data[ch] != ' ' && data[ch] != ';') {
temp[ch2] = data[ch];
printf("%c", data[ch]);
ch++;
ch2++;
}
char line[200];
ch2 = 0;
for (ch = i; ch <= sizeof(data); ch++) {
line[ch2] = data[ch];
ch2++;
}
for (ch = 0; ch <= 10; ch++) {
line[ch2] = constValues[constElem][ch];
ch2++;
}
for (ch = 0; ch <= sizeof(temp); ch++) {
line[ch2] = temp[ch];
ch2++;
}
line[ch2 + 1] = '\n';
return line[200];
}
A pointer shall point to an object before it can be derefenced. Full stop.
char **constValues[10][10]; just declares an 2D array of pointers to pointers to characters. And as it is an automatic array (neither statically nor dynamically allocated), its pointers are just uninitialized.
When you late use **constValues[constsStored][ch] = data[c];, you try to dereference an uninitialized pointer which is explicitely Undefined Behaviour. You are lucky to get an immediate crash, because UB consequences can be apparently unrelated problems.
The normal way is to declare arrays of objects, and use the addresses of those objects for pointers.
That's not all: C arrays are not first class citizens. You cannot assign to array, nor return it from a function. So this is plain wrong:
char line[200];
line[200] = createOutputLine(i, ch, data, **constValues);
It just assigns the unique character returned by the function past the end of the array!
So is this:
char line[200];
...
return line[200];
It does not return an array (C does not allow it) but the value of the byte that happens to live past the array.
I am sorry, but there are too many errors for me to fix them is such a long program.
You may find C hard and ask for help. But build small code containing only what you want to work on. And only when those small pieces work correctly, try to assemble them in a larger program.
My program takes two parameters eg "./a abc xyz" where all a's in a text file are replaced with x's and b's with y's and so on. When given a range, eg. A-C, it reads it as ABC.
The issue I am having is that when I add chars to a certain array(alphaRange2) I get a segmentation fault when I run it. I use the same code for array alphaRange1, which does accept the chars as shown when I print alphaRange1 in a for loop. When I try to print alphaRange2, no values are printed.
Here's my code:
int translate(char set1[], char set2[]) {
int c;
char ch;
char ch2;
int dash1 = 0;
int dash2 = 0;
int previous = -1;
int next;
char alphaRange1[MAXSIZE];
char alphaRange2[MAXSIZE];
size_t i;
int j = 0;
int k;
int l;
for (i=0; i <= strlen(set1); i++) {
if (set1[i] == '-') {
for (ch = set1[i-1]; ch <= set1[i+1]; ch++) {
alphaRange1[k] = ch;
k++;
}
}
}
for (i=0; i <= strlen(set2); i++) {
if (set2[i] == '-') {
for (ch = set2[i-1]; ch <= set2[i+1]; ch++) {
alphaRange2[l] = ch;
l++;
}
}
}
/*for (i=0; alphaRange1[i] != '\0'; i++) {
printf("%c", alphaRange1[i]);
}*/
while ((c = getchar()) != EOF) {
if ((dash1 == 1) && (dash2 == 1)) {
for (i=0; alphaRange1[i] != '\0' || alphaRange2[i] != '\0'; i++) {
if (c == alphaRange1[i]) {
c = alphaRange2[i];
}
}
} else if ((dash1 == 0) && (dash2 == 0)) {
for (i=0; i <= strlen(set1) || i <= strlen(set2); i++) {
if (c == set1[i]) {
c = set2[i];
if ((c == set1[1]) && (set1[1] == set2[0])) {
c = set2[0];
break;
}
}
}
}
if (previous > -1) {
putchar(previous);
}
previous = c;
}
putchar('\n');
return 1;
}
int main(int argc, char *argv[]) {
int i, j, k;
char set1[MAXSIZE];
char set2[MAXSIZE];
char ch;
char alphaRange1[MAXSIZE];
for (i=0; i < argc; i++) {
for (j=0; argv[1][j] != '\0' || argv[2][j] != '\0'; j++) {
set1[i] = argv[1][i];
set2[i] = argv[2][i];
}
}
/*for (i=0; i <= strlen(set1); i++) {
if (set1[i] == '-') {
for (ch = set1[i-1]; ch <= set1[i+1]; ch++) {
alphaRange1[k] = ch;
k++;
}
}
}
for (i=0; alphaRange1[i] != '\0'; i++) {
printf("%c", alphaRange1[i]);
}*/
translate(set1, set2);
return 1;
}
The code runs if you take out anything including alphaRange2, and I've been testing it using commented out print loop, which works if you comment out the entire while loop. How do I make this work?
Thanks.
I am trying to make a reverse Polish printer which can perform the following operation-
Inputs:
(a+(b*c))
((a+b)*(z+x))
((a+t)*((b+(a+c))^(c+d)))
Outputs:
abc*+
ab+zx+*
at+bac++cd+^*
This is my code:
#include <stdio.h>
#include <string.h>
char pop(int t);
void push(int c, int t);
int main()
{
int z;
scanf("%d", &z);
char *a[100];
int i = 0;
int q = z;
while (q-- > 0)
{
char v[400];
scanf("%s", &v);
int t;
for (t = 0; t < strlen(v); t++) //loop to put the values and signs in the 2 stacks
{
if ((v[t] == '*') || (v[t] == '+') || (v[t] == '-') || (v[t] == '^'))
{
push(v[t], 2);
}
else if (v[t] == ')')
{
int y = pop(2);
push(y, 1);
}
else
{
push(v[t], 1);
}
}
int k = 0;
char c;
while ((c = pop(1)) !='\0') //loop to put elements in the array v
{
if (c != '(')
{
v[k++] = c;
}
}
v[k--] = '\0';
int m;
for (m=0; m != k; m++, k--) //for reversing the string
{
char t = v[m];
v[m] = v[k];
v[k] = t;
}
a[i++] =v;
printf("%s",a[i - 1]);
}
int p;
for (p = 0; p <z ; p++) //printing the elements
printf("%s\n",*a[p]);
return 0;
}
char ac[400];
char as[400];
int ic = 0;
int is = 0;
void push(int c,int t)
{
if (t == 1 && ic != 400)
ac[ic++] = c;
else if (t == 2 && is != 400)
as[is++] = c;
}
char pop(int t)
{
if (t == 1 && ic != 0)
return ac[--ic];
if (t == 2 && is != 0)
return as[--is];
return '\0';
}
But it is not even inputting properly and I am not able to figure out what are the mistakes in this code.Please help to figure out what are the problems.
after inputing the no of test cases i.e.int z and first line if input
it crashes
This is due to the
printf("%s\n",*a[p]);
as BLUEPIXY noticed, *a[p] is a char; but %s expects a char *, thus you need
printf("%s\n", a[p]);
and regarding v is out of scope, the crucial factor is not the scope (visibility), but the storage duration (lifetime) of v - its lifetime ends when execution of the block with which it is associated ends, and the value of a pointer a[i] to it becomes indeterminate; by changing
a[i++] =v;
to
a[i++] = strdup(v);
you can remedy that.