How to get an array of strings without using argv - CS50 pset2 - cs50

I'm currently doing the CS50 Harvard Course and I'm stuck in problem set 2.
I made this program that takes a name and prints the initials, it takes the name in the command line. How can I use get_string() instead of argv, and argc wich is very unorthodox and sloppy, so I can prompt the user to give me her/his name. Thank you.
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(int argc, string argv[])
{
//How do I use Get_string() so I don't have to use argv and argc??
//iterate over strings on the vector (words)
for (int i = 0; i < argc; i++)
{
//prints the 0 character of each string, use "toupper" to convert into capital letters
printf("%c", toupper(argv[i][0]));
}
printf("\n");
}

use Array,
let's say for 10 names
string name[10];
for (int i = 0; i < 10; i++)
{
name[i] = get_string("Enter your name: /n");
}

Related

Wrong output with scanf function

so this is supposedly not a difficult question, but I've been getting this problem a few times when running my code in VS code. I am trying to separate the alphabets and numbers from the string, and I have used the method as follows (in my code) according to what is taught in the book. However, despite having the program running, the output is wrong.
Here is my code:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
int main(){
int weight = 0;
int height = 0;
char wunit[] = "";
char hunit[] = "";
printf("Enter the body weight: ");
scanf("%d%s",&weight,wunit);
printf("Enter the height: ");
scanf("%d%s",&height,hunit);
printf("%d,%s,%d,%s", weight, wunit, height, hunit);
return 0;
}
The thing is,if I type in 20lb for weight, and 30mt for height, what happens is that it gives the output: 20,t,30,mt; which generates this weird ‘t’ instead of lb, and I have no idea why this is the case.
Similarly, when I type 30kg for weight, and 20cm for height. It generates this weird output:30,m,0, cm. The kg becomes a 'm' and the 20 is now a '0'!? Why is that the case? The expected output would be 30,kg,20,cm
I tried simply replacing the strings, but that doesn't solve the problem fundamentally. For instance, (considering when my user puts logical inputs like lb or kg for weight), I tried this substitution and it appears to work, but doesn't fix the issue of making 20 -> 0
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
int main(){
int weight = 0;
int height= 0;
char wunit[] = "";
char hunit[] = "";
char wunit2[] = "lb";
char dummy[] = "t";
printf("Enter the body weight: ");
scanf("%d%s",&weight,wunit);
printf("Enter the height: ");
scanf("%d%s",&height,hunit);
if (strcmp(wunit,dummy)==0){
printf("%d,%s,%d,%s\n", weight, wunit2, height, hunit);
}
//printf("%d,%s,%d,%s", weight, wunit, height, hunit);
return 0;
}
I've also tried running it in codecollab, and it shows this error of "stack smashing detected" after I run it a few times, which got me more confused, what has it to do with this?
Thanks in advance.
wunit is an array of size 1 (it is initialized to "", which in chars looks like {'\0'}). What happens when you try to put lots of characters (say, "lb", which is {'l', 'b', '\0'}) into a memory location that is smaller than it should be?
scanf happily writes as many bytes as needed, smashing anything in its way ("stack-smashing", because wunit and all those local variables are stored on the stack). Try to give scanf more space, say using
char wunit[10] = "";
And never ever use "%s" directly. Limit the maximum of characters that you will allow scanf to place, for example using "%9s" to ensure that at most 9 characters + terminator (10 total) will be read.
This works for me:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
int weight = 0;
int height = 0;
char wunit[10] = "";
char hunit[10] = "";
printf("Enter the body weight: ");
scanf("%d%9s",&weight,wunit);
printf("Enter the height: ");
scanf("%d%9s",&height,hunit);
printf("%d,%s,%d,%s", weight, wunit, height, hunit);
return 0;
}
Note: scanf with %s is rightfully considered very dangerous. See https://stackoverflow.com/a/2430310/15472

I'm trying to create a string with n characters by allocating memories with malloc, but I have a problem

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n;
printf("Length? ");
scanf("%d", &n);
getchar();
char* str = (char*)malloc(sizeof(char) * (n+1));
fgets(str,sizeof(str),stdin);
for (int i = 0; i < n; i++)
printf("%c\n", str[i]);
free(str);
}
Process results like this!
Length? 5
abcde
a
b
c
?
(I wanted to upload the result image, but I got rejected since I didn't have 10 reputations)
I can't figure out why 'd' and 'e' won't be showing in the results.
What is the problem with my code??
(wellcome to stackoverflow :) (update #1)
str is a pointer to char instead of a character array therefore sizeof(str) is always 8 on 64-bit or 4 on 32-bit machines, no matter how much space you have allocated.
Demo (compilation succeeds only if X in static_assert(X) holds):
#include <assert.h>
#include <stdlib.h>
int main(void){
// Pointer to char
char *str=(char*)malloc(1024);
#if defined _WIN64 || defined __x86_64__ || defined _____LP64_____
static_assert(sizeof(str)==8);
#else
static_assert(sizeof(str)==4);
#endif
free(str);
// Character array
char arr[1024];
static_assert(sizeof(arr)==1024);
return 0;
}
fgets(char *str, int num, FILE *stream) reads until (num-1) characters have been read
Instead of fgets(str,sizeof(str),stdin) please fgets(str,n+1,stdin)
Fixed version:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main(void){
int n=0;
printf("Length? ");
scanf("%d",&n);
getchar();
char *str=(char*)calloc((n+1),sizeof(char));
static_assert(
sizeof(str)==sizeof(char*) && (
sizeof(str)==4 || // 32-bit machine
sizeof(str)==8 // 64-bit machine
)
);
fgets(str,n+1,stdin);
for(int i=0;i<n;++i)
printf("%c\n",str[i]);
free(str);
str=NULL;
}
Length? 5
abcde
a
b
c
d
e

In Ubuntu, Why the sequence is changed?

I compile this code in Ubuntu. I did it more than 10 times but I got only AAA BBB CCC . I believe sequence can be changed but I don't know why. Please somebody kindly tell me the reason.
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
void *thread_entry(void *ptr)
{
char *name = (char *)ptr;
printf("%s-A\n", name);
sleep(1); //sched_yield();
printf("%s-B\n", name);
sleep(1); //sched_yield();
printf("%s-C\n", name);
}
int main()
{
#define MAX_THREAD 3
pthread_t thread[MAX_THREAD];
char *thread_name[MAX_THREAD] = {"thread1", "thread2", "thread3"};
int i;
for (i = 0; i < MAX_THREAD; i++)
pthread_create(&thread[i], NULL, thread_entry, thread_name[i]);
for (i = 0; i < MAX_THREAD; i++)
pthread_join(thread[i], NULL);
return 0;
}
Theoretically it's possible, but it's very unlikely you would see another ordering.
You spawn 3 threads, then one of them prints "A" and waits for 1 second until it will print "B". One second of sleeping is far more than enough for the rest threads to print "A". Same for "B" and "C".

Simple Cypher Program Not Working (CS50)

On week 2 of CS50 and I've hit a wall. My code is supposed to prompt a user for plaintext and then print a simple cypher on the next line. Problem is, my code keeps printing the exact input for the user rather than scrambling. My code is below.
Note: the error in my code is likely down in the for loop, inside the respective printf functions.
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main (int argc, string argv[]){
if (argc != 2){
printf("You must enter two arguments, the second being a single digit integer!\n");
return 1;
}
int key = atoi(argv[1]);
printf("What do you want to encrpyt?");
string s = get_string();
for(int i=0; i < strlen(s); i++){
if (isupper(s[i])==true){
printf("%c",((s[i] + key)));
}
if (islower(s[i])==true){
printf("%c",s[i] + key);
}
else {
printf("%c",s[i]);
}
}
}
Fixed it. The if statement syntax was wrong, so the program was skipping over the cypher text. I need to delete the "==true" out of the if statement.

Get certain parts out of a string using C

Evening everyone hope on of you gurus can help. I am trying to find the answer to this issue I need to read the data out of the string below by searching the tags. i.e IZTAG UKPART etc however the code I am using is no good as it only stores the 1st part of it for example UKPART = 12999 and misses out the -0112. Is there a better way to search strings ?
UPDATE SO FAR.
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main ()
{
// in my application this comes from the handle and readfile
char buffer[255]="TEST999.UKPART=12999-0112...ISUE-125" ;
//
int i;
int codes[256];
char *pos = buffer;
size_t current = 0;
//
char buffer2[255];
if ((pos=strstr(pos, "UKPART")) != NULL) {
strcpy (buffer2, pos); // buffer2 <= "UKPART=12999-0112...ISUE-125"
}
printf("%s\n", buffer2);
system("pause");
return 0;
}
NOW WORKS BUT RETURN WHOLE STRING AS OUTPUT I NEED TO JUST RETURN UKPART FOR EXAMPLE THANKS SO FAR :-)
strstr() is absolutely the right way to search for the substring. Cool :)
It sounds like you want something different from "sscanf()" to copy the substring.
Q: Why not just use "strcpy ()" instead?
EXAMPLE:
char buffer[255]="IZTAG-12345...UKPART=12999-0112...ISUE-125" ;
char buffer2[255];
if ((pos=strstr(pos, "UKPART")) != NULL) {
strcpy (buffer2, pos); // buffer2 <= "UKPART=12999-0112...ISUE-125"

Resources