Cách đọc input cho đến khi gặp ký tự '\n'

Hi mọi người,
Mình có một số vấn đề thắc mắc sau về C++:

  1. Việc khai báo một mảng có kích thước lớn ở trong và ngoài hàm main có gì khác nhau ạ?
    Ví dụ đoạn CT sau sẽ bị lỗi:
#include <iostream>

using namespace std;

int main()
{
    int d[1000][1000];
    for(int i = 0; i < 1000; ++i)
        for(int j = 0; j < 1000; ++j)
            d[i][j] = i*j;
    return 0;
}

Mình có tra trên SO thì họ hướng dẫn cách fix là lôi mảng d ra ngoài hàm main hoặc để từ khóa static phía trước, hoặc cấp phát động …
Tuy mình thường code mảng toàn cục hơn nhưng trong TH này mình cũng thắc mắc vì sao như vậy? Và trong TH đó phải sửa lại kích thước mảng d bao nhiêu để ko bị lỗi khi bỏ trong hàm main?

  1. Đối với việc nhập/xuất file, để đơn giản và nhanh, mình thường để hai dòng sau đầu hàm main:
freopen("INPUT", "r", stdin);
freopen("OUTPUT", "w", stdout);

Một số bài thường yêu cầu đọc dữ liệu mà không cho biết kích thước của dữ liệu trước, chỉ cho biết mỗi dữ liệu ở một dòng, thì làm thế nào để đọc input như vậy được ạ?
VD: Cho 2 mảng, mảng A gồm n phần tử và mảng B gồm m phần tử. INPUT: dòng thứ nhất các phần tử mảng A, dòng thứ 2 các phần tử mảng B

x1 x2 x3 ... xn
y1 y2 y3 ... ym
  1. Theo mình biết kiểu long long range up khoảng 1e18. Đối với double, mình chỉ biết phần thập phân chính xác tới khoảng 15 chữ số sau dấu chấm. Vậy giới hạn ở phần nguyên là bao nhiêu ạ?

Mình cảm ơn

  1. Khai báo mảng trong main thì mảng sẽ nằm ở bộ nhớ stack, còn khai báo ngoài main thì mảng nằm trong heap.

    Kích thước của stack nhỏ hơn nhiều so với heap, nên khi khai báo mảng quá lớn trong main thì xảy ra tràn stack. Quăng ra ngoài main thì may ra code còn chạy (mảng to quá thì chịu).

  2. Nếu đã freopen (giống như pipe file vào stdin) thì chỉ cần

while (cin >> data) {
    // .. code
}
  1. Giới hạn phần nguyên là -10^308 -> 10^308.
5 Likes
  1. Vậy khai báo mảng trong main anh nghĩ kích thước bao nhiêu là an toàn ạ?

Nếu đọc vậy sao phân biệt được dữ liệu ạ?
Như ví dụ trên thì nó có đọc hết một lèo trong input không anh hay là đọc hết 1 dòng, là mảng A. Rồi đọc dòng tiếp theo, là mảng B?

Phần nguyên lớn đến vậy thì … liệu thay long long luôn được hả anh?

  1. Cỡ 1 triệu là đủ.

Như ví dụ trên thì đọc 2 dòng dưới dạng string, sau đó split string thành số thôi.

Nếu số nguyên thì cài bignum có khi còn tốt hơn dùng double nữa :smile:

5 Likes

Em có thể xin code mẫu phần nhập xuất được không ạ?
Và ngoài nhập string rồi chuyển thành số có cách nào lấy trực tiếp không anh?

Em vẫn chưa hiểu sao range phần nguyên của double lại lớn đến vậy ạ? (trong vài bài toán nó có thể kham vị trí của mấy cái int/long long luôn ấy chứ)

Code sơ sơ thì như thế này

Bonus: split dùng strtok(), tham khảo cmt dưới


Tuỳ bài thôi bạn ạ.

4 Likes

15 chữ số thôi nhé :smiley: hi sinh độ chính xác để biểu diễn số lớn hơn thôi.

4 Likes
  1. là vì stack giới hạn “chỉ” có 2MB. Có thể chỉnh giới hạn này lúc biên dịch chương trình nhưng ít/ko ai làm :V Nếu em muốn mảng chứa được nhiều hơn 2MB thì để ở heap (cấp phát động, std::vector) hoặc ở vùng data (biến toàn cục)

  2. cách dễ nhất là đọc hết vào 1 cái vector, rồi vì biết x và y có số lượng bằng nhau nên nửa đầu là x, nửa sau là y :joy:

    vector<int> xy;
    for (int n; cin >> n;)
        xy.push_back(n);
    
    // từ &xy[0] tới &xy[xy.size() / 2 - 1] là mảng x
    // từ &xy[xy.size() / 2] tới &xy[xy.size() - 1] là mảng y
    
  3. Kiểu số thực ko biết gì về phần nguyên hay phần thực hết em à :V Ví dụ em viết số Avôgadrô gì đó 6.023x1023 thì đây là số nguyên hay số thực? Là số nguyên nhưng em xài chả khác gì số thực cả. Tuy là số nguyên nhưng em chả biết chính xác hết 23 chữ số của nó, em chỉ biết chính xác tới 4 chữ số 6023. double, float cũng đối xử với dữ liệu của nó như thế :V Một số nhị phân 1.abc…uvw * 2x. Hơn nữa là chính xác 24/53 chữ số hệ nhị phân chứ ko phải thập phân, nên em đừng nghĩ chính xác 15/16 chữ số hệ thập phân là như mình tính toán, ko có :V ví dụ x.1 * 10 có thể lớn hơn hoặc bé hơn x1 (10x + 1) hoặc chính xác là x1, tùy vào x :V :V

5 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?