Minimalistic reimplementation of std::cout [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Can you please help me reimplement the most basic functionality of std::cout?
Requirements:
1) C standard headers can be included, but no C++ libraries can be used. For example stdio.h can be used for printf function.
2) It is okay if it only works with one type, let's go with "char*". The objective is to find the briefest implementation.
3) The following line should be working without any modification (namespace should be used):
std::cout << "Hello World!\n";
4) Everything should be within one file including the main() method
Edit:
Here is the code which I have, that results in a compilation error:
#include <stdio.h>
namespace std {
class cout {
public:
void operator << (char* s) {
printf("%s", s);
}
};
}
int main() {
std::cout << "Hello World!\n"; // Compilation error: expected an identifier
}
Thanks

Here is the solution, you were not refering with an operator to the object, but to the class type. You need to create an object of that type to use the << with it.
#include <stdio.h>
//don't ever use std namespace
namespace test {
class base_cout {
public:
void operator << (const char const* s) {
printf("%s",s);
}
};
// This should be extern if you want to use it outside a single file.
base_cout cout;
}
int main() {
test::cout << "Hello World\n";
}
This is what cout in iostream header is:
namespace std { extern ostream __declspec(dllexport) cout; }

Related

C++: Is there a way to pass system arguments/files directly at compilation with g++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a C++ program which uses sys.argv for loop counters and an input file to initialize std::vector's. Can I directly input those at compilation with g++?
I would also be happy with something that uses bash to do this. I am not proficient enough in either C++ or bash to figure this out myself.
Thank you in advance for answers.
C++ is compiled before it is executed. That means that the compiler won't have a list of arguments to give to the program.
Consider the scenario where you build the C++ program on one computer but then distribute the C++ program to another computer. The second computer doesn't have, or need, a compiler. How do you get your program arguments then? Consider this example in Python:
import sys
for arg in sys.argv:
print(arg)
In C++20, that might be:
#include <iostream> // std::cout
#include <cstdlib> // EXIT_SUCCESS
int main(int argc, char **argv) {
for (int i = 0; i < argc; ++i) {
std::cout << argv[i] << std::endl;
}
return EXIT_SUCCESS;
}
If you know the program arguments for the second computer when you compiled it into the first computer then you can provide it as a static variable. Consider these examples:
my_args = ["hello", "world!"]
for arg in my_args:
print(arg)
In C++20, that might be:
#include <iostream> // std::cout
#include <cstdlib> // EXIT_SUCCESS
#include <vector> // std::vector
std::vector<const char *> my_args{"hello", "world!"};
int main(int, char **) {
for (const char * arg : my_args) {
std::cout << arg << std::endl;
}
return EXIT_SUCCESS;
}

beginner in c++ and i face this problem error C3867 [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
this my first c++ project by using classes and i face this problem
error C3867
my main code is
#include <string>
#include <iostream>
#include "Car.h"
int main() {
Car c1;
c1.setMaker("Honda");
c1.setModel(2018);
cout << "This Car Made By" << c1.getMaker << "\n";
cout << "This Car Model" << c1.getModel << "\n";
}
the header is
#pragma once
#include <string>
using namespace std;
class Car {
private:
string maker;
int model;
public:
void setMaker(string m);
string getMaker();
void setModel(int m);
int getModel();
the cpp is
#include "Car.h"
void Car::setMaker(string l) { maker = l; }
string Car::getMaker() { return maker; }
void Car::setModel(int m) { model = m; }
int Car::getModel() { return model; }
and this is the error message:
error C3867: 'Car::getMaker': non-standard syntax; use '&' to create a pointer to member
i've tried everything i know as a beginner but i can't make it work :(
You need to call functions with a parameter list at the end, even if that list is empty.
E.g
c1.getMaker is the address to the getMaker function
c1.getMaker() actually calls the function

Clang compilation error on MacOS [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
This problem seems to only be present on MacOS, compilation is fine on linux also using clang.
the following code is a simplification but demonstrates the issue,
#include<iostream>
int index = 0;
int main()
{
std::cout << index << std::endl;
}
throws this error on compilation:
main.cpp:2:5: error: redefinition of 'index' as different kind of symbol
int index = 0;
^
/usr/include/strings.h:73:7: note: previous definition is here
char *index(const char *, int) __POSIX_C_DEPRECATED(200112L);
^
main.cpp:5:18: warning: address of function 'index' will always evaluate to
'true' [-Wpointer-bool-conversion]
std::cout << index << std::endl;
~~ ^~~~~
main.cpp:5:18: note: prefix with the address-of operator to silence this warning
std::cout << index << std::endl;
^
&
1 warning and 1 error generated.
These were the compiler arguments used:
clang++ -std=c++11 main.cpp -o test
when removing iostream with stdio or nothing the code compiles as expected. Is their a way to fix this or will I have to rename my variable to avoid this?
I did find this but I am already using the C++11 flag and the -std=c11 flag doesn't seem to be valid for C++ code.
The specific version of clang/xcode you're using happens to include the <strings.h> header when you include <iostream>. <strings.h> provides a function called index() at global scope. Thus, you cannot declare a variable also at global scope with the same name.
Either rename the variable, or move it into main():
#include <iostream>
int main()
{
int index = 0;
std::cout << index << std::endl;
}
This works because when a variable has the same identifier as something else but is in a different scope, it is considered a different entity altogether.
To give you an example on how that works, consider this code:
#include <iostream>
int myVar = 0;
int main()
{
int myVar = 1;
std::cout << myVar << '\n';
std::cout << ::myVar << '\n';
}
This will print:
1
0
because myVar refers to the local variable, but ::myVar to the one at global scope.
Is their a way to fix this or will I have to rename my variable to avoid this?
C++ provides namespaces specifically to avoid collisions between names. You can create one for your variable:
#include<iostream>
namespace MyGlobals {
int index = 0;
}
int main()
{
std::cout << MyGlobals::index << std::endl;
}

LINKER ERROR LNK1169 & LNK2005 [duplicate]

This question already has answers here:
C++, good old LNK1169 (and LNK2005) errors
(3 answers)
Closed 5 years ago.
I'm learning c++ and trying to practice translation units and other things at once, but I'm getting the errors listed on the title. This program is for learning purposes and I've tried to explain what each header and implementation file is suppose to do.
--------CString.h--------
#ifndef CSTRING_H
#define CSTRING_H
#include <iostream>
namespace w1
{
class CString
{
public:
char mystring[];
CString(char cstylestring[]);
void display(std::ostream &os);
};
std::ostream &operator<< (std::ostream &os, CString &c)
{
c.display(os);
return os;
}
}
#endif
--------process.h-------- prototype for process function
void process(char cstylestring[]);
--------CString.cpp--------
To receive a C-style string in constructor and truncate it by taking the first three characters and storing it in mystring to be later displayed through the function display()
#include <iostream>
#include "CString.h"
#define NUMBEROFCHARACTERS 3
using namespace w1;
w1::CString::CString(char stylestring[])
{
if (stylestring[0] == '\0')
{
mystring[0] = ' ';
}
else
{
for (int i = 0; i < NUMBEROFCHARACTERS; i++)
{
mystring[i] = stylestring[i];
}
}
//strncpy(mystring, stylestring, NUMBEROFCHARACTERS);
}
void w1::CString::display(std::ostream &os)
{
std::cout << mystring << std::endl;
}
--------process.cpp-------- receives a C-style string and creates a CString object and then display the possibly truncated version of the c-style string by operator overloading.
#include "process.h"
#include "CString.h"
#include <iostream>
using namespace std;
void process(char cstylestring[])
{
w1::CString obj(cstylestring);
std::cout << obj << std::endl;
}
--------main.cpp-------- Testing purposes by sending a C-style string to process function.
#include <iostream>
#include "process.h"
using namespace std;
int main()
{
char themainstring[] = "hiiiii";
process(themainstring);
return 0;
}
The << operator is defined multiple time because you define it in an header file that is include from multiple source files.
Either add inline modifier so that only one copy will be kept or move the definition in one source file (and only keep the declaration in the header file).
As I have mentioned in my comment, the program would crash at run time because no memory is allocated for mystring. If it should be 4 characters long maximum, then you could simply add 4 inside the square bracket as in:
char mystring[4];
Otherwise, if you need variable size, then using something like std::vector might make sense as you would avoid explicit memory management.
Update:
My original answer was complete but since you don't seem to properly understand it, I have added extra details...
I am talking of the following definition in CString.h:
std::ostream &operator<< (std::ostream &os, CString &c)
{
c.display(os);
return os;
}
Both process.cpp and main.cpp include the file CString.h which contains that definition twice (once when compiling each of these 2 files).

Is there any way to use string in c++ without the word "string" appear in the program? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
As title stated, is there any way of doing that?
I tried to use #define, and #typedef but both will require the word "string" to appear in the program.
You can use macro:
#define CO( first, second ) second##first
int main()
{
CO( ing, str ) foobar;
}
which produces this error:
error: ‘string’ was not declared in this scope
CO( ing, str ) foobar;
this shows that literal string was built, using it as a type is obvious (through using namespace std or changing str to std::str).
if you have c++14 you can use literals:
using namespace std::literals;
auto str = ""s;
decltype(str) anotherstr;
both solutions require header <string> but that can be avoided by including another system header, that directly or indirectly includes it.
but I do not really see any practical purpose of this.
Of course you can:
#define S str##ing
#define S_INCLUDE <S>
#include <iostream>
#include S_INCLUDE
int main()
{
std::S str = "Hello world!";
std::cout << str << std::endl;
}
You can do this:
#include FOOBAR_I
int main() {
std::FOOBAR foobar = "";
(void)foobar;
}
And compile it with the following command line parameters:
-DFOOBAR="string" -DFOOBAR_I="<string>"