Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
CS283
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Wendy Nguyen
CS283
Commits
f7e566e0
Commit
f7e566e0
authored
6 months ago
by
Wendy Nguyen
Browse files
Options
Downloads
Patches
Plain Diff
assignment 1
parent
3c219138
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
1-C/stringfun.c
+354
-0
354 additions, 0 deletions
1-C/stringfun.c
with
354 additions
and
0 deletions
1-C/stringfun.c
0 → 100644
+
354
−
0
View file @
f7e566e0
#include
<stdio.h>
#include
<string.h>
#include
<stdlib.h>
#define BUFFER_SZ 50
//prototypes
void
usage
(
char
*
);
void
print_buff
(
char
*
,
int
);
int
setup_buff
(
char
*
,
char
*
,
int
);
//prototypes for functions to handle required functionality
int
count_words
(
char
*
,
int
,
int
);
//add additional prototypes here
int
wordPrint
(
char
*
buff
,
char
user_str_len
);
void
reverse
(
char
*
buff
,
int
user_str_len
);
int
wordFound
(
char
*
str
,
char
*
word
);
int
replace
(
char
*
src
,
char
*
word
,
char
*
replacement
,
char
*
dest
,
int
buff_len
);
int
setup_buff
(
char
*
buff
,
char
*
user_str
,
int
len
){
//TODO: #4: Implement the setup buff as per the directions
/*
- Make all white spaces single space
- Count the length
- Return -1 if length > BUFFER_SZ
- Else: fill dots in and return length
*/
int
space
=
0
;
int
user_str_len
=
0
;
while
(
*
user_str
!=
'\0'
&&
user_str_len
<=
len
)
{
if
(
*
user_str
!=
' '
)
{
*
buff
=
*
user_str
;
buff
++
;
space
=
0
;
user_str_len
++
;
}
else
{
if
(
space
==
0
)
{
*
buff
=
*
user_str
;
buff
++
;
user_str_len
++
;
space
+=
1
;
}
}
user_str
++
;
}
if
(
*
user_str
!=
'\0'
&&
user_str_len
>
len
)
{
return
-
1
;
}
int
buff_curr_len
=
user_str_len
;
while
(
buff_curr_len
<
len
)
{
*
buff
=
'.'
;
buff
++
;
buff_curr_len
++
;
}
buff
=
buff
-
buff_curr_len
;
return
user_str_len
;
}
void
print_buff
(
char
*
buff
,
int
len
){
printf
(
"Buffer: "
);
for
(
int
i
=
0
;
i
<
len
;
i
++
){
putchar
(
*
(
buff
+
i
));
}
putchar
(
'\n'
);
}
void
usage
(
char
*
exename
){
printf
(
"usage: %s [-h|c|r|w|x]
\"
string
\"
[other args]
\n
"
,
exename
);
}
int
count_words
(
char
*
buff
,
int
len
,
int
str_len
){
if
(
str_len
==
0
)
{
return
0
;
}
int
wc
=
0
;
for
(
int
i
=
0
;
i
<
str_len
;
i
++
)
{
if
(
*
buff
==
' '
)
{
wc
+=
1
;
}
buff
++
;
}
wc
+=
1
;
return
wc
;
}
//ADD OTHER HELPER FUNCTIONS HERE FOR OTHER REQUIRED PROGRAM OPTIONS
int
wordPrint
(
char
*
buff
,
char
user_str_len
)
{
int
charCount
=
0
;
int
wordCount
=
1
;
printf
(
"Word Print
\n
----------
\n
"
);
printf
(
"%d. "
,
wordCount
);
while
(
*
buff
!=
'.'
)
{
if
(
*
buff
!=
' '
)
{
printf
(
"%c"
,
*
buff
);
charCount
++
;
}
else
{
printf
(
" (%d)
\n
"
,
charCount
);
charCount
=
0
;
wordCount
++
;
printf
(
"%d. "
,
wordCount
);
}
buff
++
;
}
printf
(
" (%d)
\n
"
,
charCount
);
printf
(
"Number of words returned: %d
\n
"
,
wordCount
);
buff
=
buff
-
user_str_len
;
}
void
reverse
(
char
*
buff
,
int
user_str_len
)
{
char
temp
;
char
*
end
=
buff
+
user_str_len
-
1
;
while
(
end
>
buff
)
{
temp
=
*
buff
;
*
buff
=
*
end
;
*
end
=
temp
;
end
--
;
buff
++
;
}
}
int
wordFound
(
char
*
str
,
char
*
word
)
{
int
wordLength
=
0
;
while
(
*
word
!=
'\0'
)
{
if
(
*
str
!=
*
word
)
{
return
0
;
// first word in string is not the wanted word
}
wordLength
++
;
str
++
;
word
++
;
}
word
=
word
-
wordLength
;
if
(
*
str
!=
' '
&&
*
str
!=
'\0'
&&
*
str
!=
'.'
)
{
return
0
;
}
str
=
str
-
wordLength
;
return
wordLength
;
}
int
replace
(
char
*
src
,
char
*
word
,
char
*
replacement
,
char
*
dest
,
int
buff_len
)
{
int
match
;
int
newWord
=
1
;
char
*
original_dst
=
dest
;
int
destLength
=
0
;
int
replmLength
=
0
;
int
wordNotFound
=
1
;
while
(
*
replacement
!=
'\0'
)
{
replmLength
++
;
replacement
++
;
}
replacement
=
replacement
-
replmLength
;
while
(
*
src
!=
'.'
)
{
if
(
newWord
)
{
match
=
wordFound
(
src
,
word
);
// if word to replace is found, copy replacement to dest instead
if
(
match
>
0
)
{
wordNotFound
=
0
;
while
(
*
replacement
!=
'\0'
)
{
destLength
++
;
if
(
destLength
>
buff_len
)
{
return
-
1
;
}
*
dest
=
*
replacement
;
dest
++
;
replacement
++
;
}
src
=
src
+
match
;
replacement
=
replacement
-
replmLength
;
}
}
if
(
*
src
==
'.'
)
{
break
;
}
destLength
++
;
if
(
destLength
>
buff_len
)
{
return
-
1
;
}
*
dest
=
*
src
;
if
(
*
src
==
' '
)
{
newWord
=
1
;
}
else
{
newWord
=
0
;
}
dest
++
;
src
++
;
}
if
(
wordNotFound
)
{
return
1
;
}
dest
=
dest
-
destLength
;
// printf("Replaced string: %s\n", dest);
return
destLength
;
}
int
main
(
int
argc
,
char
*
argv
[]){
char
*
buff
;
//placehoder for the internal buffer
char
*
input_string
;
//holds the string provided by the user on cmd line
char
opt
;
//used to capture user option from cmd line
int
rc
;
//used for return codes
int
user_str_len
;
//length of user supplied string
//TODO: #1. WHY IS THIS SAFE, aka what if arv[1] does not exist?
// This is to validate if the command has a correct syntax and all minimum required arguments
// so that the following operations can run with valid inputs or the type of error can be
// specified to help the user fix it and find the correct command that is going to work
if
((
argc
<
2
)
||
(
*
argv
[
1
]
!=
'-'
)){
usage
(
argv
[
0
]);
exit
(
1
);
}
opt
=
(
char
)
*
(
argv
[
1
]
+
1
);
//get the option flag
//handle the help flag and then exit normally
if
(
opt
==
'h'
){
usage
(
argv
[
0
]);
exit
(
0
);
}
//WE NOW WILL HANDLE THE REQUIRED OPERATIONS
//TODO: #2 Document the purpose of the if statement below
// The if statement below is to make sure the user
// uses a command with at least 1 flag and 2 required
// arguments to proceed. Otherwise, an error will
// occur and the syntax will be provided to help them
// enter the correct command
if
(
argc
<
3
){
usage
(
argv
[
0
]);
exit
(
1
);
}
input_string
=
argv
[
2
];
//capture the user input string
//TODO: #3 Allocate space for the buffer using malloc and
// handle error if malloc fails by exiting with a
// return code of 99
// CODE GOES HERE FOR #3
buff
=
malloc
(
sizeof
(
char
)
*
BUFFER_SZ
);
user_str_len
=
setup_buff
(
buff
,
input_string
,
BUFFER_SZ
);
//see todos
if
(
user_str_len
<
0
){
printf
(
"Error setting up buffer, error = %d
\n
"
,
user_str_len
);
exit
(
2
);
}
switch
(
opt
){
case
'c'
:
rc
=
count_words
(
buff
,
BUFFER_SZ
,
user_str_len
);
//you need to implement
if
(
rc
<
0
){
printf
(
"Error counting words, rc = %d"
,
rc
);
exit
(
2
);
}
printf
(
"Word Count: %d
\n
"
,
rc
);
break
;
//TODO: #5 Implement the other cases for 'r' and 'w' by extending
// the case statement options
case
'w'
:
wordPrint
(
buff
,
user_str_len
);
break
;
case
'r'
:
reverse
(
buff
,
user_str_len
);
break
;
case
'x'
:
if
(
argc
<
5
)
{
printf
(
"Not Implemented!
\n
"
);
exit
(
1
);
}
char
*
word
=
argv
[
3
];
// word to replace
char
*
replacement
=
argv
[
4
];
char
*
dest
=
malloc
(
sizeof
(
char
)
*
50
);
int
destLenght
=
replace
(
buff
,
word
,
replacement
,
dest
,
BUFFER_SZ
);
if
(
destLenght
==
-
1
)
{
printf
(
"Not implemented! Replacement is causing buffer overflow.
\n
"
);
exit
(
2
);
// overflow error
}
if
(
destLenght
==
1
)
{
printf
(
"Not implemented! Word not found.
\n
"
);
exit
(
3
);
// error with provided service
}
user_str_len
=
setup_buff
(
buff
,
dest
,
BUFFER_SZ
);
free
(
dest
);
break
;
default:
usage
(
argv
[
0
]);
exit
(
1
);
}
//TODO: #6 Dont forget to free your buffer before exiting
print_buff
(
buff
,
BUFFER_SZ
);
free
(
buff
);
exit
(
0
);
}
//TODO: #7 Notice all of the helper functions provided in the
// starter take both the buffer as well as the length. Why
// do you think providing both the pointer and the length
// is a good practice, after all we know from main() that
// the buff variable will have exactly 50 bytes?
//
// Providing both the pointer and the length is necessary
// because it will help the function keep track of the length
// of the buffer while and after each step of modification
// to avoid overflow as well as to set up the buffer after
// the string operation is complete (so that it always has
// exactly 50 bytes)
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment