Newbie syntax issue: error: expected ';' before ')' token - c

On both for loops (ie: for(len... and for(wid... ), I receive the same error message:
error: expected ';' before ')' token
void
init(void)
{
//fills board up with numbers
int tile = (d*d - 1);
int len = 0;
int wid = 0;
for(len < d; len++)
{
for(wid < d; wid++)
{
board[len][wid] = tile;
tile--;
}
}
}
Sorry to ask a similar question as before, but I'm a very confused Newbie!

Every for-loop needs to have its 3 parts (initialization, test, update) and if you don't have one or more of them, you still have to supply the two ;, so
for(len < d; len++)
^
|
should really be
|
v
for(;len < d; len++)
and the same for the other for-loop in your function.
For instance, this is how you would set up an infinite loop using for:
for(;;)
where all parts are skipped, but the two semi-colons are still required.
Perhaps this is tutorial/reference on the for-loop is helpful as a review/reference.

In general, a for loop has three parts:
for (initialization; check; update) { ... }
In your code, you are missing the initialization section.
You are missing a semi colon in your for loops to denote that you don't need an initialization clause (since you do it above):
void
init(void)
{
//fills board up with numbers
int tile = (d*d - 1);
int len = 0;
int wid = 0;
for(;len < d; len++)
{
for(;wid < d; wid++)
{
board[len][wid] = tile;
tile--;
}
}
}

Related

Problem organizing a data set chronologically

I'm here asking for your help, not because I have an error, but simply because of this solution that in my head seemed quite credible despite not working.
I basically have a structure to make an appointment and I created a variable of this temporary structure to change the values ​​so that they are in ascending order, however when I show the query table in this case, but the queries appear in the order I registered them in the program.
My Struct:
typedef struct Consulta {
char nomeUtente[70];
int numSNS;
int dia;
int mes;
int ano;
int horasInicio;
int minutosInicio;
int horasFim;
int minutosFim;
} consulta;
My function that should order the values:
void organizarAgenda(int membroEscolhido, consulta agenda[][50][50], int clinicaSelecionada, int *nFuncionarios, int *nAgendas)
{
int i, j;
boolean substituir;
consulta temp;
for (i = 0; i < nAgendas[membroEscolhido]; i++)
{
for (j = 0; j < nAgendas[membroEscolhido]; j++)
if (agenda[j][membroEscolhido][clinicaSelecionada].ano > agenda[i][membroEscolhido][clinicaSelecionada].ano)
substituir = true;
if (agenda[j][membroEscolhido][clinicaSelecionada].ano == agenda[i][membroEscolhido][clinicaSelecionada].ano
&& (agenda[j][membroEscolhido][clinicaSelecionada].mes > agenda[i][membroEscolhido][clinicaSelecionada].mes))
substituir = true;
if (agenda[j][membroEscolhido][clinicaSelecionada].ano == agenda[i][membroEscolhido][clinicaSelecionada].ano
&& (agenda[j][membroEscolhido][clinicaSelecionada].mes == agenda[i][membroEscolhido][clinicaSelecionada].mes)
&& (agenda[j][membroEscolhido][clinicaSelecionada].dia > agenda[i][membroEscolhido][clinicaSelecionada].dia))
substituir = true;
if (agenda[j][membroEscolhido][clinicaSelecionada].ano == agenda[i][membroEscolhido][clinicaSelecionada].ano
&& (agenda[j][membroEscolhido][clinicaSelecionada].mes == agenda[i][membroEscolhido][clinicaSelecionada].mes)
&& (agenda[j][membroEscolhido][clinicaSelecionada].dia == agenda[i][membroEscolhido][clinicaSelecionada].dia
&& agenda[j][membroEscolhido][clinicaSelecionada].horasInicio >= agenda[i][membroEscolhido][clinicaSelecionada].horasInicio))
substituir = true;
if (substituir == true)
{
//Igualar a variavel temporario á variável agenda em i
temp.ano = agenda[i][membroEscolhido][clinicaSelecionada].ano;
temp.mes = agenda[i][membroEscolhido][clinicaSelecionada].mes;
temp.dia = agenda[i][membroEscolhido][clinicaSelecionada].dia;
temp.horasInicio = agenda[i][membroEscolhido][clinicaSelecionada].horasInicio;
temp.minutosInicio = agenda[i][membroEscolhido][clinicaSelecionada].minutosInicio;
temp.horasFim = agenda[i][membroEscolhido][clinicaSelecionada].horasFim;
temp.minutosFim = agenda[i][membroEscolhido][clinicaSelecionada].minutosFim;
//Igualar a variável agenda em i á variável agenda em j
agenda[i][membroEscolhido][clinicaSelecionada].ano = agenda[j][membroEscolhido][clinicaSelecionada].ano;
agenda[i][membroEscolhido][clinicaSelecionada].mes = agenda[j][membroEscolhido][clinicaSelecionada].mes;
agenda[i][membroEscolhido][clinicaSelecionada].dia = agenda[j][membroEscolhido][clinicaSelecionada].dia;
agenda[i][membroEscolhido][clinicaSelecionada].horasInicio = agenda[j][membroEscolhido][clinicaSelecionada].horasInicio;
agenda[i][membroEscolhido][clinicaSelecionada].minutosInicio = agenda[j][membroEscolhido][clinicaSelecionada].minutosInicio;
agenda[i][membroEscolhido][clinicaSelecionada].horasFim = agenda[j][membroEscolhido][clinicaSelecionada].horasFim;
agenda[i][membroEscolhido][clinicaSelecionada].minutosFim = agenda[j][membroEscolhido][clinicaSelecionada].minutosFim;
//Igualar a variável agenda em j á variavel temporaria
agenda[j][membroEscolhido][clinicaSelecionada].ano = temp.ano;
agenda[j][membroEscolhido][clinicaSelecionada].mes = temp.mes;
agenda[j][membroEscolhido][clinicaSelecionada].dia = temp.dia;
agenda[j][membroEscolhido][clinicaSelecionada].horasInicio = temp.horasInicio;
agenda[j][membroEscolhido][clinicaSelecionada].minutosInicio = temp.minutosInicio;
agenda[j][membroEscolhido][clinicaSelecionada].horasFim = temp.horasFim;
agenda[j][membroEscolhido][clinicaSelecionada].minutosFim = temp.minutosFim;
}
}
Thank you all in advance!
substituir is unitialized. You need to set it to false immediately after the for statement for j.
Your for loop for j is missing a trailing { so it will only iterate over the first if and not the others [as you would probably like]
As I mentioned in my comment, simplify [please ;-)]. Use pointers to simplify the code.
Your indexing is quite complex, so I can only guess at things.
I changed the comparison logic to something I understand.
Here's a simplified version. I just coded it, so it may not compile. But, it should give you some ideas how to proceed:
typedef struct Consulta {
char nomeUtente[70];
int numSNS;
int dia;
int mes;
int ano;
int horasInicio;
int minutosInicio;
int horasFim;
int minutosFim;
} consulta;
void
organizarAgenda(int membroEscolhido, consulta agenda[][50][50],
int clinicaSelecionada, int *nFuncionarios, int *nAgendas)
{
int i;
int j;
int lim = nAgendas[membroEscolhido];
int dif;
consulta temp;
for (i = 0; i < lim; i++) {
consulta *iptr = &agenda[i][membroEscolhido][clinicaSelecionada];
for (j = 0; j < lim; j++) {
consulta *jptr = &agenda[j][membroEscolhido][clinicaSelecionada];
do {
dif = iptr->ano - jptr->ano;
if (dif)
break;
dif = iptr->mes - jptr->mes;
if (dif)
break;
dif = iptr->dia - jptr->dia;
if (dif)
break;
} while (0);
if (dif <= 0)
continue;
temp = *iptr;
*iptr = *jptr;
*jptr = temp;
}
}
}
I'm [still] guessing but I think you can get a [significant] speedup by changing the for loop for j.
And, I think the for loop for i goes one too far.
So, consider:
for (i = 0; i < (lim - 1); i++) {
consulta *iptr = &agenda[i][membroEscolhido][clinicaSelecionada];
for (j = i + 1; j < lim; j++) {
consulta *jptr = &agenda[j][membroEscolhido][clinicaSelecionada];
UPDATE:
I didn't understand how a 3d array with only a 2d array assignment works int lim = nAgendas[membroEscolhido];
The value of nAgendas[membroEscolhido] is invariant across the function, so it can be "cached". I did this to simplify the code [mostly] but it also can help the compiler generate more efficient code.
I didn't notice the (-) in the middle of this line, and the -> works because it is a pointer pointing to the struct, right?
Right. The arrow operator (->) is a very powerful way to access individual struct members if you have a pointer to the given struct instance.
Note that the compiler's optimizer might be able to see that all the variables of the form: array[x][y][z].whatever could be reduced.
But, when we use intermediate pointers we're giving it a [better] clue as to what we want. And, the code is more readable by humans, so it has two good reasons to do it.
I don't understand why you put while (0)
This is a bit of a trick [of mine] to replace an if/else ladder with something that is cleaner.
It forms a "once through" loop. It would be the equivalent of:
while (1) {
if (something)
break;
if (something_else)
break;
break; // make the loop execute _only_ once
}
For a more detailed explanation, see my answer: About the exclusiveness of the cases of an if block

Why can't I declare more than one variable in a for loop's initial statement?

When using a with one variable, we declare it to 0 as i=0 like here
but when we use two variables as if I add n = strlen to make the code more efficient then i=0 is not declared but a comma is used and n=strlen(s) is declared. Why can't we use 'i=0;' here as done in the previous code?
Edit: The cs50.h is part of the sandbox cs50 which is made by harvard.
#include <stdio.h>
#include <string.h>
int main(void)
{
string s = get_string("Input: ");
printf("Output: ");
for (int i = 0; i < strlen(s); i++)
{
printf("%c\n", s[i]);
}
}
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
string s = get_string("Input: ");
printf("Output:\n");
for (int i = 0, n = strlen(s); i < n; i++)
{
printf("%c\n", s[i]);
}
}
From C standard ISO/IEC 9899:TC3 / ISO/IEC 9899/C11, the grammar description of the for statement, §(6.8.5) iteration-statement, have 2 different forms:
for ( expression_opt ; expression_opt ; expression_opt ) statement
for (declaration expression_opt ; expression_opt ) statement
Note that in the first form we have an expression in the first position, although it is optional as all 3 fields, and all the 3 parts of the statement form are separated by a ; semicolon used as a delimiter.
In the second form we can see that the first element in parenthesis is a declaration instead of an expression, and we can note also that there is no semicolon delimiting it. This is because the declaration itself is always terminated by a semicolon.
Paragraph (6.7) declaration describe grammar for a declaration:
declaration-specifiers init-declarator-list_opt ;
As you can see a declaration is always terminated by a semicolon.
A declaration can assume of course the form of multiple declarations initialized as in your:
for (int i = 0, n = strlen(s); i < n; i++)
{
printf("%c\n", s[i]);
}
So you are using the second form where the semicolon delimits the declaration (not the first part of the for).
Using multiple semicolon is simply a grammar error.
Not sure if I understand the question (although I like it). Both your code snippets work, don't they? Note that we don't know what is in cs50.h, but I tried compiling this, and it worked (both compiling and running).
#include <stdio.h>
#include <string.h>
int main(void) {
char *s = "Hello world!";
printf("Output:\n");
for (int i = 0, n = strlen(s); i < n; i++) {
printf("%c\n", s[i]);
}
}
Two things might be relevant here;
- how for works and
- how variable declaration/initialization works.
You can think about for like this:
for(AAA; BBB; CCC) DDD;
is the same as
{ // Important!
AAA;
while(BBB) {
{
DDD;
}
CCC;
}
} // Important!
The // Important! braces are important because the for introduces a new scope, i.e. i and n won't accessible outside/after the for loop.
The other thing is declaration/initialization. So the
int i = 0, n = strlen(s);
is an initialization of two variables: i, n. I'm not 100% sure about the proper vocabulary and rules (you can consult the standard), but the idea is that a declaration looks like:
TYPE VAR1, VAR2, ..., VARn
where the VARx is a variable name declared, or an "assignment" in which case it is an initialization.
UPDATE/PART2:
Usually how I would do this is something like:
const int len = strlen(s);
// Good practice to declare const what every you know wont change
for(int i = 0; i < len; i++) {
// whatever
}
But, what if the confusing coma/semicolon could be made consistent and since the semicolon is a must let's try to make everything a semicolon, I've tried this:
for ({int i = 0; int n = strlen(s); }; i < n; i++) {
// what ever
}
This did not compile, but it also didn't make sense, since if this would have "worked" (in the sense I thought I could but actually couldn't), i and n would be declared in the small block and it wouldn't be accessible anywhere else, i.e. in i < n would not be accessible. So to make them accessible we could try this:
int i, n;
for ({i = 0; n = strlen(s); }; i < n; i++) {
printf("%c\n", s[i]);
}
Now this should have worked if the for-while equivalency stated above would be 100% true, but it's not since apparently the the AAA has to be a single statement (usually a declaration) and it can't be a block i.e. {...}. Exact compiler error:
cc hola.c -o hola
hola.c: In function ‘main’:
hola.c:8:8: error: expected expression before ‘{’ token
8 | for ({
| ^
make: *** [<builtin>: hola] Error 1
but as you can see it is already very ugly and all... so yes, you need to use , to separate the declarations/initializations and a ; to terminate it.

Obviously declared variable is considered undeclared [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have the following code* inside an if else {} code block but the GCC compiler throws me this error:
hw2b.c: In function `printSymbolK':
hw2b.c:26: parse error before `int'
hw2b.c:27: `w' undeclared (first use in this function)
hw2b.c:27: (Each undeclared identifier is reported only once
hw2b.c:27: for each function it appears in.)
*
int w = 0;
for(w = 4; w < i; w++) {
printf(" ");
}
Can someone tell me what i'm missing here? The w variable is declared and initialized inside the if else block but it says it isn't. Any ideas?
EDIT: You were right, i only copied a small piece of my program. Here is the full code:
#include <stdio.h>
/*
* The printSymbolK function accepts a
* natural number (N > 3) and prints the
* symbol K to the console according to certain
* specifications.
*/
void printSymbolK(int N) {
int i = 0,k=0;
int katoAkeraioMeros = N/2; // to apotelesma tou pilikou tha strogkilopoihtei pros ta kato dinontas mas to kato akeraio meros tou N/2
char star = '*';
for(i = 0;i < N; i++) {
if( i < katoAkeraioMeros) { // katoAkeraioMeros - i+1 = posa tha einai apo pano
int res = katoAkeraioMeros - 1; // poses fores tha trexei i epanalipsi
int l = 0;
printf("%c",star);
for(l = i;l < res;l++) {
printf(" ");
}
printf("%c\n",star);
} else if(i+1 == katoAkeraioMeros) {
printf("%c%c\n",star,star);
} else if(i > katoAkeraioMeros) { // auxise to space kata 1 gia kathe i apo edo kai pera
printf("%c",star);
int w = 0;
for(w = 4; w < i; w++) {
printf(" ");
}
printf("%c\n",star);
} else {
printf("%c %c\n",star,star);
}
}
}
int main() {
// Stelios Papamichail 4020
int n = 0;
do {
scanf("%d",&n);
printf("\n\n");
} while(n <= 3);
printSymbolK(n);
return 0;
}
the first error says it all:
hw2b.c:26: parse error before `int'
So something triggered a syntax error before the int token.
you shouldn't worry about further errors. at this point the parser is confused and thinks you're using w whereas you're trying to declare it (compilers don't stop at the first error so you can fix several errors at once, but sometimes that backfires, and sometimes they stop at some error, and when you fix it, you get more errors... compiler does its best with invalid code)
Just fix the first error, and retry.
Without seeing the full code, I would guess your using an older C compiler (C89) and you have code that is neither variable definition nor declarations above 'int w = 0;'.

code accounting for multiple delimiters isn't working

I have a program I wrote to take a string of words and, based on the delimiter that appears, separate each word and add it to an array.
I've adjusted it to account for either a ' ' , '.' or '.'. Now the goal is to adjust for multiple delimiters appearing together (as in "the dog,,,was walking") and still only add the word. While my program works, and it doesn't print out extra delimiters, every time it encounters additional delimiters, it includes a space in the output instead of ignoring them.
int main(int argc, const char * argv[]) {
char *givenString = "USA,Canada,Mexico,Bermuda,Grenada,Belize";
int stringCharCount;
//get length of string to allocate enough memory for array
for (int i = 0; i < 1000; i++) {
if (givenString[i] == '\0') {
break;
}
else {
stringCharCount++;
}
}
// counting # of commas in the original string
int commaCount = 1;
for (int i = 0; i < stringCharCount; i++) {
if (givenString[i] == ',' || givenString[i] == '.' || givenString[i] == ' ') {
commaCount++;
}
}
//declare blank Array that is the length of commas (which is the number of elements in the original string)
//char *finalArray[commaCount];
int z = 0;
char *finalArray[commaCount] ;
char *wordFiller = malloc(stringCharCount);
int j = 0;
char current = ' ';
for (int i = 0; i <= stringCharCount; i++) {
if (((givenString[i] == ',' || givenString[i] == '\0' || givenString[i] == ',' || givenString[i] == ' ') && (current != (' ' | '.' | ',')))) {
finalArray[z] = wordFiller;
wordFiller = malloc(stringCharCount);
j=0;
z++;
current = givenString[i];
}
else {
wordFiller[j++] = givenString[i];
}
}
for (int i = 0; i < commaCount; i++) {
printf("%s\n", finalArray[i]);
}
return 0;
}
This program took me hours and hours to get together (with help from more experienced developers) and I can't help but get frustrated. I'm using the debugger to my best ability but definitely need more experience with it.
/////////
I went back to pad and paper and kind of rewrote my code. Now I'm trying to store delimiters in an array and compare the elements of that array to the current string value. If they are equal, then we have come across a new word and we add it to the final string array. I'm struggling to figure out the placement and content of the "for" loop that I would use for this.
char * original = "USA,Canada,Mexico,Bermuda,Grenada,Belize";
//creating two intialized variables to count the number of characters and elements to add to the array (so we can allocate enough mmemory)
int stringCharCount = 0;
//by setting elementCount to 1, we can account for the last word that comes after the last comma
int elementCount = 1;
//calculate value of stringCharCount and elementCount to allocate enough memory for temporary word storage and for final array
for (int i = 0; i < 1000; i++) {
if (original[i] == '\0') {
break;
}
else {
stringCharCount++;
if (original[i] == ',') {
elementCount++;
}
}
}
//account for the final element
elementCount = elementCount;
char *tempWord = malloc(stringCharCount);
char *finalArray[elementCount];
int a = 0;
int b = 0;
//int c = 0;
//char *delimiters[4] = {".", ",", " ", "\0"};
for (int i = 0; i <= stringCharCount; i++) {
if (original[i] == ',' || original[i] == '\0') {
finalArray[a] = tempWord;
tempWord = malloc(stringCharCount);
tempWord[b] = '\0';
b = 0;
a++;
}
else {
tempWord[b++] = original[i];
}
}
for (int i = 0; i < elementCount; i++) {
printf("%s\n", finalArray[i]);
}
return 0;
}
Many issues. Suggest dividing code into small pieces and debug those first.
--
Un-initialize data.
// int stringCharCount;
int stringCharCount = 0;
...
stringCharCount++;
Or
int stringCharCount = strlen(givenString);
Other problems too: finalArray[] is never assigned a terminarting null character yet printf("%s\n", finalArray[i]); used.
Unclear use of char *
char *wordFiller = malloc(stringCharCount);
wordFiller = malloc(stringCharCount);
There are more bugs than lines in your code.
I'd suggest you start with something much simpler.
Work through a basic programming book with excercises.
Edit
Or, if this is about learning to program, try another, simpler programming language:
In C# your task looks rather simple:
string givenString = "USA,Canada Mexico,Bermuda.Grenada,Belize";
string [] words = string.Split(new char[] {' ', ',', '.'});
foreach(word in words)
Console.WriteLine(word);
As you see, there are much issues to worry about:
No memory management (alloc/free) this is handeled by the Garbage Collector
no pointers, so nothing can go wrong with them
powerful builtin string capabilities like Split()
foreach makes loops much simpler

Accessing an array referenced by a pointer in C

I am new to programming in C and am trying to write a simple function that will compare strings. I am coming from java so I apologize if I'm making mistakes that seem simple. I have the following code:
/* check if a query string ps (of length k) appears
in ts (of length n) as a substring
If so, return 1. Else return 0
*/
int
simple_substr_match(const unsigned char *ps, /* the query string */
int k, /* the length of the query string */
const unsigned char *ts, /* the document string (Y) */
int n /* the length of the document Y */)
{
int i;
for(i = 0;i < n;i+k){
char comp;
comp = ts->substring(i,k);
if (strncmp(comp, ps, k)) {
return 1;
}
}
return 0;
}
When trying to compile i get the error: request for member 'substring' in something not a structure or union.
The idea of the code is describe in the code comment but just to elaborate I am looking to see if ps occurs as a substring of ts in increments of k(length of ps).
What am I doing wrong and how can I fix it? Is there a better way of doing what I am trying to do?
Change
for(i = 0;i < n;i+k){
char comp;
comp = ts->substring(i,k);
if (strncmp(comp, ps, k)) {
return 1;
}
}
to
for(i = 0;i < n-k;i++){
if (!strncmp(ts+i, ps, k)) {
return 1;
}
}
ts is a char* not a class (and you're writing in C, not C++)
How about using the standard 'strstr' C function?
if (strstr(ts, ps) != NULL) {
return 1;
} else {
return 0;
}
C doesn't have member functions. and in c++ char doesn't have a member function substring.
you should use ts as an character array.
Something like this?
#define simple_substr_match(ps,ts) (strstr(ts,ps) != NULL)

Resources