CS50 How to fix error: use of undeclared identifier 'i'? - c

I'm working on my PSet2 Caesar Problem. After finishing my code here is the mistakes I got. Any advice how to fix them? Really appreciated.
caesar.c:46:10: error: use of undeclared identifier 'i'
for (i = 0; i < strlen(plaintext); i++)
^
caesar.c:46:17: error: use of undeclared identifier 'i'
for (i = 0; i < strlen(plaintext); i++)
^
caesar.c:46:40: error: use of undeclared identifier 'i'
for (i = 0; i < strlen(plaintext); i++)
^
caesar.c:48:31: error: use of undeclared identifier 'i'
if (isupper(plaintext[i]))
^
caesar.c:50:39: error: use of undeclared identifier 'i'
printf("%c", (((plaintext[i] - 65) + k) %26) + 65);
^
caesar.c:52:36: error: use of undeclared identifier 'i'
else if (islower(plaintext[i]))
^
caesar.c:54:39: error: use of undeclared identifier 'i'
printf("%c", (((plaintext[i] - 97) + k) %26) + 97);
^
caesar.c:58:36: error: use of undeclared identifier 'i'
printf("%c", plaintext[i]);
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
//Check that there is one command-line argument
if (argc != 2)
{
printf ("Usage: ./caesar key\n");
return 1;
}
else printf ("Success!\n");
//Define the key
string key = argv[1];
//Check if input is a digit
for (int i = 0; i < strlen(argv[1]); i++)
{
if (!isdigit(argv[1][i]))
{
printf ("Usage: ./caesar key\n");
return 1;
}
else printf ("Success!\n%s\n", key);
}
//Get plain text from user
string plaintext = get_string("Plaintext: ");
//Define key
int k = atoi(key);
printf("ciphertext: ");
//Obtain ciphertext
for (i = 0; i < strlen(plaintext); i++)
{
if (isupper(plaintext[i]))
{
printf("%c", (((plaintext[i] - 65) + k) %26) + 65);
}
else if (islower(plaintext[i]))
{
printf("%c", (((plaintext[i] - 97) + k) %26) + 97);
}
else
{
printf("%c", plaintext[i]);
}
}
printf("\n");
}

"use of undeclared identifier 'i'" means that you have not declared the identifier i before using it - the compiler doesn't recognize the name.
In this case the code should be for (int i = 0; ...

Good to see you're doing cs50. You have missed a little, yet important thing. Since you have not declared the variable i outside any loop, thus, it is only available to that loop. So, when you are using it anywhere outside the loop, it's actually undeclared variable, and that's what is happening here.
So, you need to declare i in the last for loop too. I've attached the modified code.
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
//Check that there is one command-line argument
if (argc != 2)
{
printf ("Usage: ./caesar key\n");
return 1;
}
else printf ("Success!\n");
//Define the key
string key = argv[1];
//Check if input is a digit
for (int i = 0; i < strlen(argv[1]); i++)
{
if (!isdigit(argv[1][i]))
{
printf ("Usage: ./caesar key\n");
return 1;
}
else printf ("Success!\n%s\n", key);
}
//Get plain text from user
string plaintext = get_string("Plaintext: ");
//Define key
int k = atoi(key);
printf("ciphertext: ");
//Obtain ciphertext
for (int i = 0; i < strlen(plaintext); i++) // declared i
{
if (isupper(plaintext[i]))
{
printf("%c", (((plaintext[i] - 65) + k) %26) + 65);
}
else if (islower(plaintext[i]))
{
printf("%c", (((plaintext[i] - 97) + k) %26) + 97);
}
else
{
printf("%c", plaintext[i]);
}
}
printf("\n");
}

I may be wrong, but could you not implement as a prototype inside main, so that it finds and refers to it later? Example:
int main(void) {
int i;
//all your code here
}
I don't know for sure that this would work, but typically when I get the error you have, doing this fixes it.

Related

substitution cs50 - handle repeating characters in key

This code is for the CS50 Harvard course Pset 2 substitution.
one section of my program requires a check on the key to make sure characters are not repeated. I am failing this check as it reads ' :( Handles duplicate characters in Key - timed out while waiting for program to exit'
What needs to be fixed in my code to pass this final check?
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, string argv[])
{
printf("\n");
//check if we have correct number of command line arguments
if (argc != 2)
{
printf("Usage: ./substitution key\n");
printf("(Please enter only 2 command line arguments)\n");
return 1; //error
}
//initialize global variables for use//
//length of key
int s = strlen(argv[1]);
//copy of key may be altered if it is not valid yet
string k = argv[1];
// if else to check if our key is 26 characters
if (s == 26)
{
for (int i = 0; i < 26; i++)
{
//checks each index in k to see if it is alpha or not, throws error if not
if (!isalpha(k[i]))
{
printf("Usage: ./substitution key\n");
printf("(Key must be alphabetical)\n");
return 1; //error
}
}
for (int i = 0; i < s; i++)
{
for (int j = i + 1; j < s; j++)
{
if (isupper(k[i]))
{
k[i] = tolower(k[i]);
}
if (k[i] == k[j])
{
printf("Usage: ./substitution key\n");
printf("(Key can not have repeating characters)\n");
return 1; //error
}
}
}
}
else
{
//if we dont have 26 characters
printf("Usage: ./subsitution key\n");
printf("Key must be 26 characters\n");
return 1;
}
//true key for our cipher
string key = k;
//ask user for plaintext
string plaintext = get_string("Plaintext: ");
int n = strlen(plaintext);
printf("ciphertext: ");
char *ciphertext = malloc(n);
for (int i = 0; i < n; i++)
{
//plaintext = Hello (H - 65 = 7 (8TH INDEX) IN OUR KEY)
if (isalpha(plaintext[i]))
{
if (isupper(plaintext[i]))
{
int j = plaintext[i] - 'A';
printf("%c", toupper(key[j]));
}
if (islower(plaintext[i]))
{
int q = plaintext[i] - 'a';
printf("%c", tolower(key[q]));
}
}
else if (isdigit(plaintext[i]))
{
printf("%c", plaintext[i]);
}
else
{
printf("%c", plaintext[i]);
}
}
printf("\n");
}
check50 tells you what argument it uses for the test. When you run your code with that argument, does it complain about duplicate characters in the key?
This program will not find a duplicate if the second occurance of a character is in upper case.

CS50 clang-10: error: linker command failed with exit code 1 (use -v to see invocation)

I'm taking the course Harvard CS50x and this is the caesar problem set.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("Nope\n");
return 1;
}
int k = atoi(argv[1]);
if (k < 0)
{
printf("Nope\n");
return 1;
}
else
{
string code = GetString();
for (int i = 0, n = strlen(code); i < n; i++)
{
if islower(code[i])
printf("%c", (((code[i] + k) - 97) % 26) + 97);
else if isupper(code[i])
printf("%c", (((code[i] + k) - 65) % 26) + 65);
else
printf("%c", code[i]);
}
printf("\n");
return 0;
}
}
I don't understand what the problem is with this code but when I try to compile I get this:
To use the function atoi you need to include the header <stdlib.h>
#include <stdlib.h>
It seems the function GetString is not declared in the header <cs50.h>. Instead try to use the function get_string. For example
string code = get_string( "Enter a text: " );
These if statements
if islower(code[i])
printf("%c", (((code[i] + k) - 97) % 26) + 97);
else if isupper(code[i])
are incorrect. Expressions used in if statements shall be enclosed in pafrentheses. For example
if ( islower( ( unsigned char )code[i] ) )
printf("%c", (((code[i] + k) - 97) % 26) + 97);
else if ( isupper( ( unsigned char )code[i] ) )
Also it is a bad idea to use magic numbers like for example 97 or 65. Instead use 'a' and 'A'.

Segmentation fault clang

what I try to do
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, string argv[]) {
for (int i = 0; i < strlen(argv[1]); i++) {
if (isalpha(atoi(argv[i]))) {
printf("Usage: ./caesar key\n");
return 1;
}
}
int k = atoi(argv[1]);
if (argc == 2) {
string pt = get_string("plaintext: ");
printf("ciphertext: ");
char ct[strlen(pt)];
for (int i = 0; i < (strlen(pt)); i++) {
if (isalpha(pt[i]) && isupper(pt[i])) {
ct[i] = ((pt[i] - 65) + k) % 26;
printf("%c", ct[i] + 65);
} else if (isalpha(pt[i]) && islower(pt[i])) {
ct[i] = ((pt[i] - 97) + k) % 26;
printf("%c", ct[i] + 97);
}
}
printf("\n");
}
else if (argc != 2) {
printf("Usage: ./caesar keyn\n");
return 1;
}
}
if I pass 20x it must show me (Usage: ./caesar)
instead of that I get Segmentation fault why!!
can anyone help me and I will be thanx
Your first loop iterates through the number of characters in the first command argument, and tries to access the command argument of that index. So if you have only one command argument, but that argument has more than 2 characters then you will be trying to access an element in argv beyond the end of the array.

CS50 "expected expression" for else statement in C?

I can't seem to find the reason for my last remaining bug. Sadly I dont have any real life developer friends I can hast for quick help so making this post was my only option.
error given is
57:13: error: expected expression
else
^
could someone maybe check over my code and hint me towards the problem ?
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main(int argc, string argv[])
{
// make sure command line input correct.
if (argc != 2)
{
printf("Command line arguments can't be greater or lower then 2\n");
return 1;
}
// get a valid key = key
string key = (argv[1]);
int lengthK = strlen(key);
for (int i = 0; i < lengthK; i++)
{
if (!isalpha(key))
printf("Key must be alphabetical \n");
return 1;
}
//get plaintext
string(plaintext) = get_string("Plaintext : ");
//convert plaintext and keeping upper/lowercase in mind
int i;
int lengthP;
int index;
printf("ciphertext: ");
for (i = 0, index = 0, lengthP = strlen(plaintext); i < lengthP; i++)
{
if (isalpha(plaintext[i]))
{
//change uppercase letters
if (isupper(plaintext[i]))
{
printf("%c", (((plaintext[i] - 'A') + toupper(key[index]) - 'A') % 26) + 'A');
}
//change lowercase letters
if (islower(plaintext[i]))
{
printf("%c", (((plaintext[i] - 'a') + key[index] - 'A') % 26) + 'a');
}
index = (index + 1) % lengthK;
//rest
else
{
printf("%c", (plaintext[i]));
}
}
}
printf("\n");
}
This is because your syntax is invalid.
The way you wrote it is interpreted that way
if (someConditions)
{
/* do something */
}
someInstructions(); /* the if is now over since the curly brackets are closed and there was no else */
/* here is an else without if, which is a non sense */
else
{
/* do something else */
}
You either
Misplaced that instruction index = (index + 1) % lengthK;
Misplaced the closing curly bracket of if (isalpha(plaintext[i]))
You have a closing brace in the wrong place:
if (isalpha(plaintext[i]))
{
...
index = (index + 1) % lengthK;
//rest
else
{
printf("%c", (plaintext[i]));
}
} // <---- here
You need to move it above the else:
if (isalpha(plaintext[i]))
{
...
index = (index + 1) % lengthK;
}
//rest
else
{
printf("%c", (plaintext[i]));
}

Struggling with Vigenere! (In C) invalid operands to binary expression ('int *' and 'int') and other things

we are now working with caesar, vigenere. I mannaged to finish caesar but vigenere is not working as good. C gives me back: invalid operands to binary expression ('int *' and 'int'). I'm not sure what the program means exactly and what is wrong with my code. Can somebody help me out or give me advice? I think it's because I can not count with the different types of numbers? I'm not sure!
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("You have to input a key, try again!\n");
return 1;
}
string key = argv[1];
int keylength = strlen(key);
for (int i = 0; i < keylength; i++)
{
if (!isalpha(argv[1][i]))
{
printf("Please insert letters, nothing else\n");
return 1;
}
}
printf("plaintext: ");
string plain = get_string();
int keycipher[keylength];
for(int i = 0; i < keylength; i++)
{
keycipher[i] = toupper(key[i]) - 65;
}
if (plain != 0)
{
printf("ciphertext: ");
int i;
for (i = 0, keylength = strlen(key); i < keylength; i++)
{
if (isupper(plain[i]))
{
printf("%c", (plain[i] - 65 + keycipher) % 26);
}
else if (islower(plain[i]))
{
printf("%c", (plain[i] - 97 + keycipher) % 26);
}
else if (plain[i] == ' ')
{
printf(" ");
}
else
{
printf("%c", plain[i]);
}
}
}
return 0;
}
As mentioned in the comments, you have to use + keycipher[index] instead of + keycipher. This is because keycipher is an array and you need to use only one of the elements of the array at a time.
Further, you will need 2 counter variables instead of just one in the part where you find the ciphertext. This is because you need to increment the plaintext index and the key index in every iteration, but once the plaintext length crosses the key length, you will need to reset the key index.
If you check the specifications, you will understand what I am saying about using 2 counters.

Resources